ReactOS  0.4.15-dev-1152-g6c94e4f
class.h File Reference
#include <ntdddisk.h>
#include <ntddcdrm.h>
#include <ntddtape.h>
#include <ntddchgr.h>
#include <ntddstor.h>
#include "ntddscsi.h"
#include <stdio.h>
Include dependency graph for class.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _DEVICE_EXTENSION
 
struct  _COMPLETION_CONTEXT
 

Macros

#define DebugPrint(x)
 
#define MAXIMUM_RETRIES   4
 

Typedefs

typedef VOID(* PCLASS_ERROR) (IN PDEVICE_OBJECT DeviceObject, IN PSCSI_REQUEST_BLOCK Srb, IN OUT NTSTATUS *Status, IN OUT BOOLEAN *Retry)
 
typedef struct _DEVICE_EXTENSION DEVICE_EXTENSION
 
typedef struct _DEVICE_EXTENSIONPDEVICE_EXTENSION
 
typedef struct _COMPLETION_CONTEXT COMPLETION_CONTEXT
 
typedef struct _COMPLETION_CONTEXTPCOMPLETION_CONTEXT
 

Functions

NTSTATUS ScsiClassGetCapabilities (IN PDEVICE_OBJECT PortDeviceObject, OUT PIO_SCSI_CAPABILITIES *PortCapabilities)
 
NTSTATUS ScsiClassGetInquiryData (IN PDEVICE_OBJECT PortDeviceObject, IN PSCSI_ADAPTER_BUS_INFO *ConfigInfo)
 
NTSTATUS ScsiClassReadDriveCapacity (IN PDEVICE_OBJECT DeviceObject)
 
VOID ScsiClassReleaseQueue (IN PDEVICE_OBJECT DeviceObject)
 
NTSTATUS ScsiClassRemoveDevice (IN PDEVICE_OBJECT PortDeviceObject, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun)
 
NTSTATUS ScsiClassAsynchronousCompletion (PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
 
VOID ScsiClassSplitRequest (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN ULONG MaximumBytes)
 
NTSTATUS ScsiClassDeviceControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
NTSTATUS ScsiClassIoComplete (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
NTSTATUS ScsiClassIoCompleteAssociated (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
 
BOOLEAN ScsiClassInterpretSenseInfo (IN PDEVICE_OBJECT DeviceObject, IN PSCSI_REQUEST_BLOCK Srb, IN UCHAR MajorFunctionCode, IN ULONG IoDeviceCode, IN ULONG RetryCount, OUT NTSTATUS *Status)
 
NTSTATUS ScsiClassSendSrbSynchronous (PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
 
NTSTATUS ScsiClassSendSrbAsynchronous (PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, PIRP Irp, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
 
VOID ScsiClassBuildRequest (PDEVICE_OBJECT DeviceObject, PIRP Irp)
 
ULONG ScsiClassModeSense (IN PDEVICE_OBJECT DeviceObject, IN PCHAR ModeSenseBuffer, IN ULONG Length, IN UCHAR PageMode)
 
BOOLEAN ScsiClassModeSelect (IN PDEVICE_OBJECT DeviceObject, IN PCHAR ModeSelectBuffer, IN ULONG Length, IN BOOLEAN SavePage)
 
PVOID ScsiClassFindModePage (IN PCHAR ModeSenseBuffer, IN ULONG Length, IN UCHAR PageMode)
 
NTSTATUS ScsiClassClaimDevice (IN PDEVICE_OBJECT PortDeviceObject, IN PSCSI_INQUIRY_DATA LunInfo, IN BOOLEAN Release, OUT PDEVICE_OBJECT *NewPortDeviceObject OPTIONAL)
 
NTSTATUS ScsiClassInternalIoControl (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
 

Macro Definition Documentation

◆ DebugPrint

#define DebugPrint (   x)

Definition at line 41 of file class.h.

◆ MAXIMUM_RETRIES

#define MAXIMUM_RETRIES   4

Definition at line 54 of file class.h.

Typedef Documentation

◆ COMPLETION_CONTEXT

◆ DEVICE_EXTENSION

◆ PCLASS_ERROR

Definition at line 58 of file class.h.

◆ PCOMPLETION_CONTEXT

◆ PDEVICE_EXTENSION

Function Documentation

◆ ScsiClassAsynchronousCompletion()

NTSTATUS ScsiClassAsynchronousCompletion ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp,
PVOID  Context 
)

Definition at line 1217 of file class2.c.

1246 {
1248  PSCSI_REQUEST_BLOCK srb;
1249 
1250  srb = &context->Srb;
1251 
1252  //
1253  // If this is an execute srb, then check the return status and make sure.
1254  // the queue is not frozen.
1255  //
1256 
1257  if (srb->Function == SRB_FUNCTION_EXECUTE_SCSI) {
1258 
1259  //
1260  // Check for a frozen queue.
1261  //
1262 
1263  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
1264 
1265  //
1266  // Unfreeze the queue getting the device object from the context.
1267  //
1268 
1269  ScsiClassReleaseQueue(context->DeviceObject);
1270  }
1271  }
1272 
1273  //
1274  // Free the context and the Irp.
1275  //
1276 
1277  if (Irp->MdlAddress != NULL) {
1278  MmUnlockPages(Irp->MdlAddress);
1279  IoFreeMdl(Irp->MdlAddress);
1280 
1281  Irp->MdlAddress = NULL;
1282  }
1283 
1285  IoFreeIrp(Irp);
1286 
1287  //
1288  // Indicate the I/O system should stop processing the Irp completion.
1289  //
1290 
1292 
1293 } // ScsiClassAsynchronousCompletion()
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
Definition: http.c:7094
_In_ PIRP Irp
Definition: csq.h:116
VOID NTAPI MmUnlockPages(IN PMDL Mdl)
Definition: mdlsup.c:1439
UCHAR SrbStatus
Definition: srb.h:243
VOID NTAPI ScsiClassReleaseQueue(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:939
smooth NULL
Definition: ftsmooth.c:416
UCHAR Function
Definition: srb.h:242
VOID NTAPI IoFreeMdl(PMDL Mdl)
Definition: iomdl.c:146
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:378
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
struct tagContext Context
Definition: acpixf.h:1034
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by ScsiClassReleaseQueue(), and StartUnit().

◆ ScsiClassBuildRequest()

VOID ScsiClassBuildRequest ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 2970 of file class2.c.

3004 {
3005  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3008  LARGE_INTEGER startingOffset = currentIrpStack->Parameters.Read.ByteOffset;
3009  PSCSI_REQUEST_BLOCK srb;
3010  PCDB cdb;
3011  ULONG logicalBlockAddress;
3012  USHORT transferBlocks;
3013 
3014  ASSERT(*(PULONG)deviceExtension != '2slc');
3015 
3016  //
3017  // Calculate relative sector address.
3018  //
3019 
3020  logicalBlockAddress = (ULONG)(Int64ShrlMod32(startingOffset.QuadPart, deviceExtension->SectorShift));
3021 
3022  //
3023  // Allocate an Srb.
3024  //
3025 
3026  srb = ExAllocateFromNPagedLookasideList(&deviceExtension->SrbLookasideListHead);
3027 
3028  srb->SrbFlags = 0;
3029 
3030  //
3031  // Write length to SRB.
3032  //
3033 
3035 
3036  //
3037  // Set up IRP Address.
3038  //
3039 
3040  srb->OriginalRequest = Irp;
3041 
3042  //
3043  // Set up target ID and logical unit number.
3044  //
3045 
3046  srb->PathId = deviceExtension->PathId;
3047  srb->TargetId = deviceExtension->TargetId;
3048  srb->Lun = deviceExtension->Lun;
3050  srb->DataBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
3051 
3052  //
3053  // Save byte count of transfer in SRB Extension.
3054  //
3055 
3056  srb->DataTransferLength = currentIrpStack->Parameters.Read.Length;
3057 
3058  //
3059  // Initialize the queue actions field.
3060  //
3061 
3063 
3064  //
3065  // Queue sort key is Relative Block Address.
3066  //
3067 
3068  srb->QueueSortKey = logicalBlockAddress;
3069 
3070  //
3071  // Indicate auto request sense by specifying buffer and size.
3072  //
3073 
3074  srb->SenseInfoBuffer = deviceExtension->SenseData;
3076 
3077  //
3078  // Set timeout value of one unit per 64k bytes of data.
3079  //
3080 
3081  srb->TimeOutValue = ((srb->DataTransferLength + 0xFFFF) >> 16) *
3082  deviceExtension->TimeOutValue;
3083 
3084  //
3085  // Zero statuses.
3086  //
3087 
3088  srb->SrbStatus = srb->ScsiStatus = 0;
3089  srb->NextSrb = 0;
3090 
3091  //
3092  // Indicate that 10-byte CDB's will be used.
3093  //
3094 
3095  srb->CdbLength = 10;
3096 
3097  //
3098  // Fill in CDB fields.
3099  //
3100 
3101  cdb = (PCDB)srb->Cdb;
3102 
3103  //
3104  // Zero 12 bytes for Atapi Packets
3105  //
3106 
3108 
3109  cdb->CDB10.LogicalUnitNumber = deviceExtension->Lun;
3110  transferBlocks = (USHORT)(currentIrpStack->Parameters.Read.Length >> deviceExtension->SectorShift);
3111 
3112  //
3113  // Move little endian values into CDB in big endian format.
3114  //
3115 
3116  cdb->CDB10.LogicalBlockByte0 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte3;
3117  cdb->CDB10.LogicalBlockByte1 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte2;
3118  cdb->CDB10.LogicalBlockByte2 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte1;
3119  cdb->CDB10.LogicalBlockByte3 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte0;
3120 
3121  cdb->CDB10.TransferBlocksMsb = ((PFOUR_BYTE)&transferBlocks)->Byte1;
3122  cdb->CDB10.TransferBlocksLsb = ((PFOUR_BYTE)&transferBlocks)->Byte0;
3123 
3124  //
3125  // Set transfer direction flag and Cdb command.
3126  //
3127 
3128  if (currentIrpStack->MajorFunction == IRP_MJ_READ) {
3129 
3130  DebugPrint((3, "ScsiClassBuildRequest: Read Command\n"));
3131 
3132  srb->SrbFlags |= SRB_FLAGS_DATA_IN;
3133  cdb->CDB10.OperationCode = SCSIOP_READ;
3134 
3135  } else {
3136 
3137  DebugPrint((3, "ScsiClassBuildRequest: Write Command\n"));
3138 
3139  srb->SrbFlags |= SRB_FLAGS_DATA_OUT;
3140  cdb->CDB10.OperationCode = SCSIOP_WRITE;
3141  }
3142 
3143  //
3144  // If this is not a write-through request, then allow caching.
3145  //
3146 
3147  if (!(currentIrpStack->Flags & SL_WRITE_THROUGH)) {
3148 
3150 
3151  } else {
3152 
3153  //
3154  // If write caching is enable then force media access in the
3155  // cdb.
3156  //
3157 
3158  if (deviceExtension->DeviceFlags & DEV_WRITE_CACHE) {
3159  cdb->CDB10.ForceUnitAccess = TRUE;
3160  }
3161  }
3162 
3163  //
3164  // Or in the default flags from the device object.
3165  //
3166 
3167  srb->SrbFlags |= deviceExtension->SrbFlags;
3168 
3169  //
3170  // Set up major SCSI function.
3171  //
3172 
3173  nextIrpStack->MajorFunction = IRP_MJ_SCSI;
3174 
3175  //
3176  // Save SRB address in next stack for port driver.
3177  //
3178 
3179  nextIrpStack->Parameters.Scsi.Srb = srb;
3180 
3181  //
3182  // Save retry count in current IRP stack.
3183  //
3184 
3185  currentIrpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
3186 
3187  //
3188  // Set up IoCompletion routine address.
3189  //
3190 
3192 
3193  return;
3194 
3195 } // end ScsiClassBuildRequest()
struct _FOUR_BYTE * PFOUR_BYTE
ULONG SrbFlags
Definition: srb.h:252
PVOID OriginalRequest
Definition: srb.h:258
UCHAR Cdb[16]
Definition: srb.h:271
#define MmGetMdlVirtualAddress(_Mdl)
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
PVOID DataBuffer
Definition: srb.h:255
ULONG DataTransferLength
Definition: srb.h:253
Definition: cdrw_hw.h:28
UCHAR CdbLength
Definition: srb.h:250
struct _SCSI_REQUEST_BLOCK * NextSrb
Definition: srb.h:257
UCHAR QueueAction
Definition: srb.h:249
struct _CDB::_CDB10 CDB10
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
ULONG TimeOutValue
Definition: srb.h:254
UCHAR SrbStatus
Definition: srb.h:243
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
#define DEV_WRITE_CACHE
Definition: class2.h:21
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
#define IRP_MJ_SCSI
#define MAXIMUM_RETRIES
Definition: cdrom.h:124
UCHAR ScsiStatus
Definition: srb.h:244
#define SCSIOP_READ
Definition: cdrw_hw.h:905
#define SCSIOP_WRITE
Definition: cdrw_hw.h:906
union _CDB * PCDB
void * PVOID
Definition: retypes.h:9
UCHAR TargetId
Definition: srb.h:246
UCHAR Function
Definition: srb.h:242
USHORT Length
Definition: srb.h:241
NTSTATUS NTAPI ScsiClassIoComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: class2.c:1492
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define MAXIMUM_CDB_SIZE
Definition: srb.h:33
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define Int64ShrlMod32(a, b)
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
UCHAR SenseInfoBufferLength
Definition: srb.h:251
UCHAR PathId
Definition: srb.h:245
unsigned short USHORT
Definition: pedump.c:61
#define SRB_SIMPLE_TAG_REQUEST
Definition: srb.h:415
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
unsigned int * PULONG
Definition: retypes.h:1
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:393
#define SRB_FLAGS_ADAPTER_CACHE_ENABLE
Definition: srb.h:397
#define SL_WRITE_THROUGH
Definition: iotypes.h:1804
#define IRP_MJ_READ
Definition: rdpdr.c:46
PVOID SenseInfoBuffer
Definition: srb.h:256
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
ULONG QueueSortKey
Definition: srb.h:262
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by CdRomSwitchModeCompletion(), ScsiCdRomStartIo(), ScsiClassReadWrite(), and ScsiClassSplitRequest().

◆ ScsiClassClaimDevice()

NTSTATUS ScsiClassClaimDevice ( IN PDEVICE_OBJECT  PortDeviceObject,
IN PSCSI_INQUIRY_DATA  LunInfo,
IN BOOLEAN  Release,
OUT PDEVICE_OBJECT *NewPortDeviceObject  OPTIONAL 
)

Definition at line 4489 of file class2.c.

4520 {
4521  IO_STATUS_BLOCK ioStatus;
4522  PIRP irp;
4523  PIO_STACK_LOCATION irpStack;
4524  KEVENT event;
4525  NTSTATUS status;
4526  SCSI_REQUEST_BLOCK srb;
4527 
4528  PAGED_CODE();
4529 
4530  if (NewPortDeviceObject != NULL) {
4531  *NewPortDeviceObject = NULL;
4532  }
4533 
4534  //
4535  // Clear the SRB fields.
4536  //
4537 
4538  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
4539 
4540  //
4541  // Write length to SRB.
4542  //
4543 
4545 
4546  //
4547  // Set SCSI bus address.
4548  //
4549 
4550  srb.PathId = LunInfo->PathId;
4551  srb.TargetId = LunInfo->TargetId;
4552  srb.Lun = LunInfo->Lun;
4553 
4556 
4557  //
4558  // Set the event object to the unsignaled state.
4559  // It will be used to signal request completion.
4560  //
4561 
4563 
4564  //
4565  // Build synchronous request with no transfer.
4566  //
4567 
4569  PortDeviceObject,
4570  NULL,
4571  0,
4572  NULL,
4573  0,
4574  TRUE,
4575  &event,
4576  &ioStatus);
4577 
4578  if (irp == NULL) {
4579 
4580  DebugPrint((1, "ScsiClassClaimDevice: Can't allocate Irp\n"));
4582  }
4583 
4584  irpStack = IoGetNextIrpStackLocation(irp);
4585 
4586  //
4587  // Save SRB address in next stack for port driver.
4588  //
4589 
4590  irpStack->Parameters.Scsi.Srb = &srb;
4591 
4592  //
4593  // Set up IRP Address.
4594  //
4595 
4596  srb.OriginalRequest = irp;
4597 
4598  //
4599  // Call the port driver with the request and wait for it to complete.
4600  //
4601 
4602  status = IoCallDriver(PortDeviceObject, irp);
4603  if (status == STATUS_PENDING) {
4604 
4606  status = ioStatus.Status;
4607  }
4608 
4609  //
4610  // If this is a release request, then just decrement the reference count
4611  // and return. The status does not matter.
4612  //
4613 
4614  if (Release) {
4615 
4616  //ObDereferenceObject(PortDeviceObject);
4617  return STATUS_SUCCESS;
4618  }
4619 
4620  if (!NT_SUCCESS(status)) {
4621  return status;
4622  }
4623 
4624  ASSERT(srb.DataBuffer != NULL);
4625 
4626  //
4627  // Reference the new port driver object so that it will not go away while
4628  // it is being used.
4629  //
4630 
4632  0,
4633  NULL,
4634  KernelMode );
4635 
4636  if (!NT_SUCCESS(status)) {
4637 
4638  return status;
4639  }
4641 
4642  //
4643  // Return the new port device object pointer.
4644  //
4645 
4646  if (NewPortDeviceObject != NULL) {
4647  *NewPortDeviceObject = srb.DataBuffer;
4648  }
4649 
4650  return status;
4651 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PVOID OriginalRequest
Definition: srb.h:258
#define TRUE
Definition: types.h:120
PVOID DataBuffer
Definition: srb.h:255
LONG NTSTATUS
Definition: precomp.h:26
#define SRB_FUNCTION_CLAIM_DEVICE
Definition: srb.h:308
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define FALSE
Definition: types.h:117
#define SRB_FUNCTION_RELEASE_DEVICE
Definition: srb.h:313
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI ObReferenceObjectByPointer(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode)
Definition: obref.c:383
UCHAR TargetId
Definition: srb.h:246
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
UCHAR Function
Definition: srb.h:242
USHORT Length
Definition: srb.h:241
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
struct _cl_event * event
Definition: glext.h:7739
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define IOCTL_SCSI_EXECUTE_NONE
Definition: cdrw_hw.h:1453
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
UCHAR PathId
Definition: srb.h:245
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_In_ BOOLEAN Release
Definition: cdrom.h:920
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
static SERVICE_STATUS status
Definition: service.c:31
#define PAGED_CODE()
Definition: ps.c:97

◆ ScsiClassDeviceControl()

NTSTATUS ScsiClassDeviceControl ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 3603 of file class2.c.

3629 {
3631  PIO_STACK_LOCATION nextStack;
3632  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3633  PSCSI_REQUEST_BLOCK srb;
3634  PCDB cdb;
3635  NTSTATUS status;
3636  ULONG modifiedIoControlCode;
3637 
3638  ASSERT(*(PULONG)deviceExtension != '2slc');
3639 
3640  if (irpStack->Parameters.DeviceIoControl.IoControlCode ==
3642 
3643  Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
3646  goto SetStatusAndReturn;
3647  }
3648 
3649  //
3650  // If this is a pass through I/O control, set the minor function code
3651  // and device address and pass it to the port driver.
3652  //
3653 
3654  if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_PASS_THROUGH
3655  || irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_PASS_THROUGH_DIRECT) {
3656 
3657  PSCSI_PASS_THROUGH scsiPass;
3658 
3659  nextStack = IoGetNextIrpStackLocation(Irp);
3660 
3661  //
3662  // Validate the user buffer.
3663  //
3664 
3665  if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SCSI_PASS_THROUGH)){
3666 
3667  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
3670  goto SetStatusAndReturn;
3671  }
3672 
3673  //
3674  // Force the SCSI address to the correct value.
3675  //
3676 
3677  scsiPass = Irp->AssociatedIrp.SystemBuffer;
3678  scsiPass->PathId = deviceExtension->PathId;
3679  scsiPass->TargetId = deviceExtension->TargetId;
3680  scsiPass->Lun = deviceExtension->Lun;
3681 
3682  //
3683  // NOTICE: The SCSI-II specification indicates that this field
3684  // should be zero; however, some target controllers ignore the logical
3685  // unit number in the IDENTIFY message and only look at the logical
3686  // unit number field in the CDB.
3687  //
3688 
3689  scsiPass->Cdb[1] |= deviceExtension->Lun << 5;
3690 
3691  nextStack->Parameters = irpStack->Parameters;
3692  nextStack->MajorFunction = irpStack->MajorFunction;
3693  nextStack->MinorFunction = IRP_MN_SCSI_CLASS;
3694 
3695  status = IoCallDriver(deviceExtension->PortDeviceObject, Irp);
3696  goto SetStatusAndReturn;
3697  }
3698 
3699  if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_GET_ADDRESS) {
3700 
3701  PSCSI_ADDRESS scsiAddress = Irp->AssociatedIrp.SystemBuffer;
3702 
3703  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
3704  sizeof(SCSI_ADDRESS)) {
3705 
3706  //
3707  // Indicate unsuccessful status and no data transferred.
3708  //
3709 
3710  Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
3711  Irp->IoStatus.Information = 0;
3714  goto SetStatusAndReturn;
3715 
3716  }
3717 
3718  scsiAddress->Length = sizeof(SCSI_ADDRESS);
3719  scsiAddress->PortNumber = deviceExtension->PortNumber;
3720  scsiAddress->PathId = deviceExtension->PathId;
3721  scsiAddress->TargetId = deviceExtension->TargetId;
3722  scsiAddress->Lun = deviceExtension->Lun;
3723  Irp->IoStatus.Information = sizeof(SCSI_ADDRESS);
3724  Irp->IoStatus.Status = STATUS_SUCCESS;
3727  goto SetStatusAndReturn;
3728  }
3729 
3730  if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME) {
3731 
3732  UNIMPLEMENTED;
3733  Irp->IoStatus.Information = 0;
3734  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
3737  goto SetStatusAndReturn;
3738  }
3739 
3740  if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_MOUNTDEV_QUERY_UNIQUE_ID) {
3741 
3742  //
3743  // FIXME
3744  // This is a HACK. We don't have unique ID.
3745  // We'll just return device name as unique ID.
3746  // It's unique but may not survive to a reboot,
3747  // which is not matching the requirements for
3748  // a MountMgr unique ID.
3749  //
3750 
3751  PMOUNTDEV_UNIQUE_ID uniqueId = Irp->AssociatedIrp.SystemBuffer;
3752 
3753  //
3754  // Check output buffer is big enough.
3755  //
3756 
3757  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_UNIQUE_ID)) {
3758 
3759  Irp->IoStatus.Information = 0;
3760  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
3763  goto SetStatusAndReturn;
3764  }
3765 
3766  //
3767  // Set size we'll return so that caller can allocate big enough buffer.
3768  //
3769 
3770  RtlZeroMemory(uniqueId, sizeof(MOUNTDEV_UNIQUE_ID));
3771  uniqueId->UniqueIdLength = deviceExtension->DeviceName.Length;
3772 
3773  //
3774  // Check buffer is big enough to contain device name.
3775  //
3776 
3777  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId) + uniqueId->UniqueIdLength) {
3778 
3779  Irp->IoStatus.Information = sizeof(MOUNTDEV_UNIQUE_ID);
3780  Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
3783  goto SetStatusAndReturn;
3784  }
3785 
3786  //
3787  // Copy device name.
3788  //
3789 
3790  RtlCopyMemory(uniqueId->UniqueId, deviceExtension->DeviceName.Buffer,
3791  uniqueId->UniqueIdLength);
3793 
3794  //
3795  // And return to the caller.
3796  //
3797 
3798  Irp->IoStatus.Status = STATUS_SUCCESS;
3799  Irp->IoStatus.Information = FIELD_OFFSET(MOUNTDEV_UNIQUE_ID, UniqueId) + uniqueId->UniqueIdLength;
3801  goto SetStatusAndReturn;
3802  }
3803 
3804  if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_MOUNTDEV_QUERY_DEVICE_NAME) {
3805 
3806  PMOUNTDEV_NAME name = Irp->AssociatedIrp.SystemBuffer;
3807 
3808  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_NAME)) {
3809 
3810  Irp->IoStatus.Information = 0;
3811  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
3814  goto SetStatusAndReturn;
3815  }
3816 
3817  RtlZeroMemory(name, sizeof(MOUNTDEV_NAME));
3818  name->NameLength = deviceExtension->DeviceName.Length;
3819 
3820  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < FIELD_OFFSET(MOUNTDEV_NAME, Name) + name->NameLength) {
3821 
3822  Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
3823  Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
3826  goto SetStatusAndReturn;
3827  }
3828 
3829  RtlCopyMemory(name->Name, deviceExtension->DeviceName.Buffer,
3830  name->NameLength);
3832  Irp->IoStatus.Status = STATUS_SUCCESS;
3833  Irp->IoStatus.Information = FIELD_OFFSET(MOUNTDEV_NAME, Name) + name->NameLength;
3835  goto SetStatusAndReturn;
3836  }
3837 
3839 
3840  if (srb == NULL) {
3841 
3842  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
3845  goto SetStatusAndReturn;
3846  }
3847 
3848  //
3849  // Write zeros to Srb.
3850  //
3851 
3853 
3854  cdb = (PCDB)srb->Cdb;
3855 
3856  //
3857  // Change the device type to disk for the switch statement.
3858  //
3859 
3860  modifiedIoControlCode = (irpStack->Parameters.DeviceIoControl.IoControlCode
3861  & ~0xffff0000) | (IOCTL_DISK_BASE << 16);
3862 
3863  switch (modifiedIoControlCode) {
3864 
3865  case IOCTL_DISK_CHECK_VERIFY: {
3866 
3867  PIRP irp2 = NULL;
3868  PIO_STACK_LOCATION newStack;
3869 
3870  DebugPrint((1,"ScsiDeviceIoControl: Check verify\n"));
3871 
3872  //
3873  // If a buffer for a media change count was provided, make sure it's
3874  // big enough to hold the result
3875  //
3876 
3877  if(irpStack->Parameters.DeviceIoControl.OutputBufferLength) {
3878 
3879  //
3880  // If the buffer is too small to hold the media change count
3881  // then return an error to the caller
3882  //
3883 
3884  if(irpStack->Parameters.DeviceIoControl.OutputBufferLength <
3885  sizeof(ULONG)) {
3886 
3887  DebugPrint((3,"ScsiDeviceIoControl: media count "
3888  "buffer too small\n"));
3889 
3890  Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
3891  Irp->IoStatus.Information = 0;
3892  ExFreePool(srb);
3895  goto SetStatusAndReturn;
3896 
3897  }
3898 
3899  //
3900  // The caller has provided a valid buffer. Allocate an additional
3901  // irp and stick the CheckVerify completion routine on it. We will
3902  // then send this down to the port driver instead of the irp the
3903  // caller sent in
3904  //
3905 
3906  DebugPrint((2,"ScsiDeviceIoControl: Check verify wants "
3907  "media count\n"));
3908 
3909  //
3910  // Allocate a new irp to send the TestUnitReady to the port driver
3911  //
3912 
3913  irp2 = IoAllocateIrp((CCHAR) (DeviceObject->StackSize + 3), FALSE);
3914 
3915  if(irp2 == NULL) {
3916  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
3917  Irp->IoStatus.Information = 0;
3918  ExFreePool(srb);
3921  goto SetStatusAndReturn;
3922  }
3923 
3924  irp2->Tail.Overlay.Thread = Irp->Tail.Overlay.Thread;
3926 
3927  //
3928  // Set the top stack location and shove the master Irp into the
3929  // top location
3930  //
3931 
3932  newStack = IoGetCurrentIrpStackLocation(irp2);
3933  newStack->Parameters.Others.Argument1 = Irp;
3934  newStack->DeviceObject = DeviceObject;
3935 
3936  //
3937  // Stick the check verify completion routine onto the stack
3938  // and prepare the irp for the port driver
3939  //
3940 
3943  NULL,
3944  TRUE,
3945  TRUE,
3946  TRUE);
3947 
3949  newStack = IoGetCurrentIrpStackLocation(irp2);
3950  newStack->DeviceObject = DeviceObject;
3951 
3952  //
3953  // Mark the master irp as pending - whether the lower level
3954  // driver completes it immediately or not this should allow it
3955  // to go all the way back up.
3956  //
3957 
3959 
3960  Irp = irp2;
3961 
3962  }
3963 
3964  //
3965  // Test Unit Ready
3966  //
3967 
3968  srb->CdbLength = 6;
3969  cdb->CDB6GENERIC.OperationCode = SCSIOP_TEST_UNIT_READY;
3970 
3971  //
3972  // Set timeout value.
3973  //
3974 
3975  srb->TimeOutValue = deviceExtension->TimeOutValue;
3976 
3977  //
3978  // Since this routine will always hand the request to the
3979  // port driver if there isn't a data transfer to be done
3980  // we don't have to worry about completing the request here
3981  // on an error
3982  //
3983 
3985  srb,
3986  Irp,
3987  NULL,
3988  0,
3989  FALSE);
3990 
3991  break;
3992  }
3993 
3994  case IOCTL_DISK_MEDIA_REMOVAL: {
3995 
3996  PPREVENT_MEDIA_REMOVAL MediaRemoval = Irp->AssociatedIrp.SystemBuffer;
3997 
3998  //
3999  // Prevent/Allow media removal.
4000  //
4001 
4002  DebugPrint((3,"DiskIoControl: Prevent/Allow media removal\n"));
4003 
4004  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
4005  sizeof(PREVENT_MEDIA_REMOVAL)) {
4006 
4007  //
4008  // Indicate unsuccessful status and no data transferred.
4009  //
4010 
4011  Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
4012  Irp->IoStatus.Information = 0;
4013  ExFreePool(srb);
4016  goto SetStatusAndReturn;
4017  }
4018 
4019  //
4020  // Get physical device extension. This is where the
4021  // lock count is stored.
4022  //
4023 
4024  deviceExtension = deviceExtension->PhysicalDevice->DeviceExtension;
4025 
4026  //
4027  // If command succeeded then increment or decrement lock counter.
4028  //
4029 
4030  if (MediaRemoval->PreventMediaRemoval) {
4031 
4032  //
4033  // This is a lock command. Reissue the command in case bus or device
4034  // was reset and lock cleared.
4035  //
4036 
4037  InterlockedIncrement(&deviceExtension->LockCount);
4038 
4039  DebugPrint((1,
4040  "ScsiClassDeviceControl: Lock media, lock count %x on disk %x\n",
4041  deviceExtension->LockCount,
4042  deviceExtension->DeviceNumber));
4043 
4044  } else {
4045 
4046  //
4047  // This is an unlock command.
4048  //
4049 
4050  if (!deviceExtension->LockCount ||
4051  (InterlockedDecrement(&deviceExtension->LockCount) != 0)) {
4052 
4053  DebugPrint((1,
4054  "ScsiClassDeviceControl: Unlock media, lock count %x on disk %x\n",
4055  deviceExtension->LockCount,
4056  deviceExtension->DeviceNumber));
4057 
4058  //
4059  // Don't unlock because someone still wants it locked.
4060  //
4061 
4062  Irp->IoStatus.Status = STATUS_SUCCESS;
4063  ExFreePool(srb);
4066  goto SetStatusAndReturn;
4067  }
4068 
4069  DebugPrint((1,
4070  "ScsiClassDeviceControl: Unlock media, lock count %x on disk %x\n",
4071  deviceExtension->LockCount,
4072  deviceExtension->DeviceNumber));
4073  }
4074 
4075  srb->CdbLength = 6;
4076 
4077  cdb->MEDIA_REMOVAL.OperationCode = SCSIOP_MEDIUM_REMOVAL;
4078 
4079  //
4080  // TRUE - prevent media removal.
4081  // FALSE - allow media removal.
4082  //
4083 
4084  cdb->MEDIA_REMOVAL.Prevent = MediaRemoval->PreventMediaRemoval;
4085 
4086  //
4087  // Set timeout value.
4088  //
4089 
4090  srb->TimeOutValue = deviceExtension->TimeOutValue;
4092  srb,
4093  Irp,
4094  NULL,
4095  0,
4096  FALSE);
4097 
4098  //
4099  // Some devices will not support lock/unlock.
4100  // Pretend that it worked.
4101  //
4102 
4103  break;
4104  }
4105 
4106  case IOCTL_DISK_RESERVE: {
4107 
4108  //
4109  // Reserve logical unit.
4110  //
4111 
4112  srb->CdbLength = 6;
4113 
4114  cdb->CDB6GENERIC.OperationCode = SCSIOP_RESERVE_UNIT;
4115 
4116  //
4117  // Set timeout value.
4118  //
4119 
4120  srb->TimeOutValue = deviceExtension->TimeOutValue;
4121 
4123  srb,
4124  Irp,
4125  NULL,
4126  0,
4127  FALSE);
4128 
4129  break;
4130  }
4131 
4132  case IOCTL_DISK_RELEASE: {
4133 
4134  //
4135  // Release logical unit.
4136  //
4137 
4138  srb->CdbLength = 6;
4139 
4140  cdb->CDB6GENERIC.OperationCode = SCSIOP_RELEASE_UNIT;
4141 
4142  //
4143  // Set timeout value.
4144  //
4145 
4146  srb->TimeOutValue = deviceExtension->TimeOutValue;
4147 
4149  srb,
4150  Irp,
4151  NULL,
4152  0,
4153  FALSE);
4154 
4155  break;
4156  }
4157 
4158  case IOCTL_DISK_EJECT_MEDIA: {
4159 
4160  //
4161  // Eject media.
4162  //
4163 
4164  srb->CdbLength = 6;
4165 
4166  cdb->START_STOP.OperationCode = SCSIOP_START_STOP_UNIT;
4167  cdb->START_STOP.LoadEject = 1;
4168  cdb->START_STOP.Start = 0;
4169 
4170  //
4171  // Set timeout value.
4172  //
4173 
4174  srb->TimeOutValue = deviceExtension->TimeOutValue;
4176  srb,
4177  Irp,
4178  NULL,
4179  0,
4180  FALSE);
4181  break;
4182  }
4183 
4184  case IOCTL_DISK_LOAD_MEDIA: {
4185 
4186  //
4187  // Load media.
4188  //
4189 
4190  DebugPrint((3,"CdRomDeviceControl: Load media\n"));
4191 
4192  srb->CdbLength = 6;
4193 
4194  cdb->START_STOP.OperationCode = SCSIOP_START_STOP_UNIT;
4195  cdb->START_STOP.LoadEject = 1;
4196  cdb->START_STOP.Start = 1;
4197 
4198  //
4199  // Set timeout value.
4200  //
4201 
4202  srb->TimeOutValue = deviceExtension->TimeOutValue;
4204  srb,
4205  Irp,
4206  NULL,
4207  0,
4208  FALSE);
4209 
4210  break;
4211  }
4212 
4214 
4215  //
4216  // Search for devices that have been powered on since the last
4217  // device search or system initialization.
4218  //
4219 
4220  DebugPrint((3,"CdRomDeviceControl: Find devices\n"));
4221  status = DriverEntry(DeviceObject->DriverObject,
4222  NULL);
4223 
4224  Irp->IoStatus.Status = status;
4225  ExFreePool(srb);
4227 
4228  break;
4229  }
4230 
4231  default: {
4232 
4233  DebugPrint((3,"ScsiIoDeviceControl: Unsupported device IOCTL\n"));
4234 
4235  //
4236  // Pass the device control to the next driver.
4237  //
4238 
4239  ExFreePool(srb);
4240 
4241  //
4242  // Copy the Irp stack parameters to the next stack location.
4243  //
4244 
4245  nextStack = IoGetNextIrpStackLocation(Irp);
4246  nextStack->Parameters = irpStack->Parameters;
4247  nextStack->MajorFunction = irpStack->MajorFunction;
4248  nextStack->MinorFunction = irpStack->MinorFunction;
4249 
4250  status = IoCallDriver(deviceExtension->PortDeviceObject, Irp);
4251  break;
4252  }
4253 
4254  } // end switch( ...
4255 
4256 SetStatusAndReturn:
4257 
4258  return status;
4259 }
UCHAR PathId
Definition: scsi_port.h:149
UCHAR PortNumber
Definition: scsi_port.h:148
#define SCSIOP_RESERVE_UNIT
Definition: cdrw_hw.h:892
#define IOCTL_DISK_BASE
Definition: ntdddisk.h:44
#define IOCTL_DISK_EJECT_MEDIA
Definition: cdrw_usr.h:177
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define IOCTL_SCSI_GET_ADDRESS
Definition: scsi_port.h:52
UCHAR Cdb[16]
Definition: srb.h:271
struct _CDB::_MEDIA_REMOVAL MEDIA_REMOVAL
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define SCSIOP_RELEASE_UNIT
Definition: cdrw_hw.h:893
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
ULONG Length
Definition: scsi_port.h:147
USHORT UniqueIdLength
Definition: imports.h:138
#define IOCTL_DISK_CHECK_VERIFY
Definition: cdrw_usr.h:175
#define SCSIOP_TEST_UNIT_READY
Definition: cdrw_hw.h:866
#define IOCTL_STORAGE_RESET_DEVICE
Definition: ntddstor.h:140
UCHAR CdbLength
Definition: srb.h:250
ULONG TimeOutValue
Definition: srb.h:254
UCHAR TargetId
Definition: scsi_port.h:150
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
#define IOCTL_DISK_FIND_NEW_DEVICES
Definition: cdrw_usr.h:181
#define IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
Definition: imports.h:93
UCHAR Cdb[16]
Definition: scsi_port.h:71
#define IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
Definition: imports.h:80
NTSTATUS NTAPI ScsiClassCheckVerifyComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: class2.c:4910
#define FALSE
Definition: types.h:117
NTSTATUS NTAPI DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
Definition: class2.c:126
struct _MOUNTDEV_NAME MOUNTDEV_NAME
smooth NULL
Definition: ftsmooth.c:416
union _CDB * PCDB
#define IoCompleteRequest
Definition: irp.c:1240
struct _CDB::_START_STOP START_STOP
struct _MOUNTDEV_UNIQUE_ID MOUNTDEV_UNIQUE_ID
char CCHAR
Definition: typedefs.h:51
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3202
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
BOOLEAN PreventMediaRemoval
Definition: ntddstor.h:343
#define InterlockedDecrement
Definition: armddk.h:52
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define SCSIOP_MEDIUM_REMOVAL
Definition: cdrw_hw.h:902
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define IOCTL_SCSI_PASS_THROUGH
Definition: scsi_port.h:47
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
NTSTATUS NTAPI ScsiClassSendSrbAsynchronous(PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, PIRP Irp, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
Definition: class2.c:3370
#define InterlockedIncrement
Definition: armddk.h:53
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define IOCTL_SCSI_PASS_THROUGH_DIRECT
Definition: scsi_port.h:51
#define IOCTL_DISK_LOAD_MEDIA
Definition: cdrw_usr.h:178
#define IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME
Definition: imports.h:99
struct _CDB::_CDB6GENERIC CDB6GENERIC
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
Definition: name.c:38
struct _SCSI_ADDRESS SCSI_ADDRESS
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:581
#define UNIMPLEMENTED
Definition: debug.h:115
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
#define IRP_MN_SCSI_CLASS
#define IOCTL_DISK_MEDIA_REMOVAL
Definition: cdrw_usr.h:176
#define IOCTL_DISK_RESERVE
Definition: cdrw_usr.h:179
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
IoMarkIrpPending(Irp)
static SERVICE_STATUS status
Definition: service.c:31
UCHAR UniqueId[1]
Definition: imports.h:139
#define IOCTL_DISK_RELEASE
Definition: cdrw_usr.h:180
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2676
#define SCSIOP_START_STOP_UNIT
Definition: cdrw_hw.h:897
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
Definition: ps.c:97

Referenced by CdRomDeviceControl(), and ScsiDiskDeviceControl().

◆ ScsiClassFindModePage()

PVOID ScsiClassFindModePage ( IN PCHAR  ModeSenseBuffer,
IN ULONG  Length,
IN UCHAR  PageMode 
)

◆ ScsiClassGetCapabilities()

NTSTATUS ScsiClassGetCapabilities ( IN PDEVICE_OBJECT  PortDeviceObject,
OUT PIO_SCSI_CAPABILITIES PortCapabilities 
)

Definition at line 531 of file class2.c.

560 {
561  PIRP irp;
562  IO_STATUS_BLOCK ioStatus;
563  KEVENT event;
565 
566  PAGED_CODE();
567 
568  //
569  // Create notification event object to be used to signal the
570  // request completion.
571  //
572 
574 
575  //
576  // Build the synchronous request to be sent to the port driver
577  // to perform the request.
578  //
579 
581  PortDeviceObject,
582  NULL,
583  0,
584  PortCapabilities,
585  sizeof(PVOID),
586  FALSE,
587  &event,
588  &ioStatus);
589 
590  if (irp == NULL) {
592  }
593 
594  //
595  // Pass request to port driver and wait for request to complete.
596  //
597 
598  status = IoCallDriver(PortDeviceObject, irp);
599 
600  if (status == STATUS_PENDING) {
602  return(ioStatus.Status);
603  }
604 
605  return status;
606 
607 } // end ScsiClassGetCapabilities()
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define FALSE
Definition: types.h:117
smooth NULL
Definition: ftsmooth.c:416
#define STATUS_PENDING
Definition: ntstatus.h:82
struct _cl_event * event
Definition: glext.h:7739
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
PIRP NTAPI IoBuildDeviceIoControlRequest(IN ULONG IoControlCode, IN PDEVICE_OBJECT DeviceObject, IN PVOID InputBuffer, IN ULONG InputBufferLength, IN PVOID OutputBuffer, IN ULONG OutputBufferLength, IN BOOLEAN InternalDeviceIoControl, IN PKEVENT Event, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:881
#define IOCTL_SCSI_GET_CAPABILITIES
Definition: scsi_port.h:50
static SERVICE_STATUS status
Definition: service.c:31
#define PAGED_CODE()
Definition: ps.c:97

◆ ScsiClassGetInquiryData()

NTSTATUS ScsiClassGetInquiryData ( IN PDEVICE_OBJECT  PortDeviceObject,
IN PSCSI_ADAPTER_BUS_INFO ConfigInfo 
)

◆ ScsiClassInternalIoControl()

NTSTATUS ScsiClassInternalIoControl ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp 
)

Definition at line 4656 of file class2.c.

4685 {
4687  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
4688  PSCSI_REQUEST_BLOCK srb;
4689 
4690  ASSERT(*(PULONG)deviceExtension != '2slc');
4691 
4692  //
4693  // Get a pointer to the SRB.
4694  //
4695 
4696  srb = irpStack->Parameters.Scsi.Srb;
4697 
4698  //
4699  // Set SCSI bus address.
4700  //
4701 
4702  srb->PathId = deviceExtension->PathId;
4703  srb->TargetId = deviceExtension->TargetId;
4704  srb->Lun = deviceExtension->Lun;
4705 
4706  //
4707  // NOTICE: The SCSI-II specification indicates that this field should be
4708  // zero; however, some target controllers ignore the logical unit number
4709  // in the IDENTIFY message and only look at the logical unit number field
4710  // in the CDB.
4711  //
4712 
4713  srb->Cdb[1] |= deviceExtension->Lun << 5;
4714 
4715  //
4716  // Set the parameters in the next stack location.
4717  //
4718 
4719  irpStack = IoGetNextIrpStackLocation(Irp);
4720 
4721  irpStack->Parameters.Scsi.Srb = srb;
4722  irpStack->MajorFunction = IRP_MJ_SCSI;
4723  irpStack->MinorFunction = IRP_MN_SCSI_CLASS;
4724 
4726  return IoCallDriver(deviceExtension->PortDeviceObject, Irp);
4727 }
UCHAR Cdb[16]
Definition: srb.h:271
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
#define IRP_MJ_SCSI
NTSTATUS NTAPI ClassIoCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: class2.c:4731
smooth NULL
Definition: ftsmooth.c:416
UCHAR TargetId
Definition: srb.h:246
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
UCHAR PathId
Definition: srb.h:245
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IRP_MN_SCSI_CLASS
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107

Referenced by ScsiClassInitialize().

◆ ScsiClassInterpretSenseInfo()

BOOLEAN ScsiClassInterpretSenseInfo ( IN PDEVICE_OBJECT  DeviceObject,
IN PSCSI_REQUEST_BLOCK  Srb,
IN UCHAR  MajorFunctionCode,
IN ULONG  IoDeviceCode,
IN ULONG  RetryCount,
OUT NTSTATUS Status 
)

Definition at line 2148 of file class2.c.

2184 {
2185  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
2186  PDEVICE_EXTENSION physicalExtension = deviceExtension->PhysicalDevice->DeviceExtension;
2187  PSENSE_DATA senseBuffer = Srb->SenseInfoBuffer;
2188  BOOLEAN retry = TRUE;
2189  BOOLEAN logError = FALSE;
2190  ULONG badSector = 0;
2191  ULONG uniqueId = 0;
2192  NTSTATUS logStatus;
2193  ULONG readSector;
2194  ULONG index;
2195  PIO_ERROR_LOG_PACKET errorLogEntry;
2196 #if DBG
2197  ULONG i;
2198 #endif
2199 
2200  ASSERT(*(PULONG)deviceExtension != '2slc');
2201 
2202  //
2203  // Check that request sense buffer is valid.
2204  //
2205 
2206 #if DBG
2207  DebugPrint((3, "Opcode %x\nParameters: ",Srb->Cdb[0]));
2208  for (i = 1; i < 12; i++) {
2209  DebugPrint((3,"%x ",Srb->Cdb[i]));
2210  }
2211  DebugPrint((3,"\n"));
2212 #endif
2213 
2214  if (Srb->SrbStatus & SRB_STATUS_AUTOSENSE_VALID &&
2215  Srb->SenseInfoBufferLength >= FIELD_OFFSET(SENSE_DATA, CommandSpecificInformation)) {
2216 
2217  DebugPrint((1,"ScsiClassInterpretSenseInfo: Error code is %x\n",
2218  senseBuffer->ErrorCode));
2219  DebugPrint((1,"ScsiClassInterpretSenseInfo: Sense key is %x\n",
2220  senseBuffer->SenseKey));
2221  DebugPrint((1, "ScsiClassInterpretSenseInfo: Additional sense code is %x\n",
2222  senseBuffer->AdditionalSenseCode));
2223  DebugPrint((1, "ScsiClassInterpretSenseInfo: Additional sense code qualifier is %x\n",
2224  senseBuffer->AdditionalSenseCodeQualifier));
2225 
2226  //
2227  // Zero the additional sense code and additional sense code qualifier
2228  // if they were not returned by the device.
2229  //
2230 
2231  readSector = senseBuffer->AdditionalSenseLength +
2232  FIELD_OFFSET(SENSE_DATA, AdditionalSenseLength);
2233 
2234  if (readSector > Srb->SenseInfoBufferLength) {
2235  readSector = Srb->SenseInfoBufferLength;
2236  }
2237 
2238  if (readSector <= FIELD_OFFSET(SENSE_DATA, AdditionalSenseCode)) {
2239  senseBuffer->AdditionalSenseCode = 0;
2240  }
2241 
2243  senseBuffer->AdditionalSenseCodeQualifier = 0;
2244  }
2245 
2246  switch (senseBuffer->SenseKey & 0xf) {
2247 
2248  case SCSI_SENSE_NOT_READY:
2249 
2250  DebugPrint((1,"ScsiClassInterpretSenseInfo: Device not ready\n"));
2252 
2253  switch (senseBuffer->AdditionalSenseCode) {
2254 
2256 
2257  DebugPrint((1,"ScsiClassInterpretSenseInfo: Lun not ready\n"));
2258 
2259  switch (senseBuffer->AdditionalSenseCodeQualifier) {
2260 
2262 
2263  DebugPrint((1, "ScsiClassInterpretSenseInfo:"
2264  " In process of becoming ready\n"));
2265  break;
2266 
2268 
2269  DebugPrint((1, "ScsiClassInterpretSenseInfo:"
2270  " Manual intervention required\n"));
2272  retry = FALSE;
2273  break;
2274 
2276 
2277  DebugPrint((1, "ScsiClassInterpretSenseInfo: Format in progress\n"));
2278  retry = FALSE;
2279  break;
2280 
2282 
2283  default:
2284 
2285  DebugPrint((1, "ScsiClassInterpretSenseInfo:"
2286  " Initializing command required\n"));
2287 
2288  //
2289  // This sense code/additional sense code
2290  // combination may indicate that the device
2291  // needs to be started. Send an start unit if this
2292  // is a disk device.
2293  //
2294 
2295  if (deviceExtension->DeviceFlags & DEV_SAFE_START_UNIT) {
2297  }
2298 
2299  break;
2300 
2301  } // end switch (senseBuffer->AdditionalSenseCodeQualifier)
2302 
2303  break;
2304 
2306 
2307  DebugPrint((1,
2308  "ScsiClassInterpretSenseInfo:"
2309  " No Media in device.\n"));
2311  retry = FALSE;
2312 
2313  //
2314  // signal autorun that there isn't any media in the device
2315  //
2316 
2317  if((deviceExtension->MediaChangeEvent != NULL)&&
2318  (!deviceExtension->MediaChangeNoMedia)) {
2319  KeSetEvent(deviceExtension->MediaChangeEvent,
2320  (KPRIORITY) 0,
2321  FALSE);
2322  DebugPrint((0, "ScsiClassInterpretSenseInfo:"
2323  "Detected No Media In Device "
2324  "[irp = 0x%lx]\n", Srb->OriginalRequest));
2325  deviceExtension->MediaChangeNoMedia = TRUE;
2326  }
2327 
2328  break;
2329  } // end switch (senseBuffer->AdditionalSenseCode)
2330 
2331  break;
2332 
2334 
2335  DebugPrint((1, "ScsiClassInterpretSenseInfo: Media write protected\n"));
2337  retry = FALSE;
2338  break;
2339 
2341 
2342  DebugPrint((1,"ScsiClassInterpretSenseInfo: Bad media\n"));
2344 
2345  retry = FALSE;
2346  logError = TRUE;
2347  uniqueId = 256;
2348  logStatus = 0;//IO_ERR_BAD_BLOCK;
2349  break;
2350 
2352 
2353  DebugPrint((1,"ScsiClassInterpretSenseInfo: Hardware error\n"));
2355 
2356  logError = TRUE;
2357  uniqueId = 257;
2358  logStatus = 0;//IO_ERR_CONTROLLER_ERROR;
2359 
2360  break;
2361 
2363 
2364  DebugPrint((1, "ScsiClassInterpretSenseInfo: Illegal SCSI request\n"));
2366 
2367  switch (senseBuffer->AdditionalSenseCode) {
2368 
2370  DebugPrint((1, "ScsiClassInterpretSenseInfo: Illegal command\n"));
2371  retry = FALSE;
2372  break;
2373 
2375  DebugPrint((1, "ScsiClassInterpretSenseInfo: Illegal block address\n"));
2377  retry = FALSE;
2378  break;
2379 
2381  DebugPrint((1,"ScsiClassInterpretSenseInfo: Invalid LUN\n"));
2383  retry = FALSE;
2384  break;
2385 
2387  DebugPrint((1,"ScsiClassInterpretSenseInfo: Music area\n"));
2388  retry = FALSE;
2389  break;
2390 
2392  DebugPrint((1,"ScsiClassInterpretSenseInfo: Data area\n"));
2393  retry = FALSE;
2394  break;
2395 
2397  DebugPrint((1, "ScsiClassInterpretSenseInfo: Volume overflow\n"));
2398  retry = FALSE;
2399  break;
2400 
2402  DebugPrint((1, "ScsiClassInterpretSenseInfo: Invalid CDB\n"));
2403 
2404  //
2405  // Check if write cache enabled.
2406  //
2407 
2408  if (deviceExtension->DeviceFlags & DEV_WRITE_CACHE) {
2409 
2410  //
2411  // Assume FUA is not supported.
2412  //
2413 
2414  deviceExtension->DeviceFlags &= ~DEV_WRITE_CACHE;
2415  retry = TRUE;
2416 
2417  } else {
2418  retry = FALSE;
2419  }
2420 
2421  break;
2422 
2423  } // end switch (senseBuffer->AdditionalSenseCode)
2424 
2425  break;
2426 
2428 
2429  switch (senseBuffer->AdditionalSenseCode) {
2431  DebugPrint((1, "ScsiClassInterpretSenseInfo: Media changed\n"));
2432 
2433  if(deviceExtension->MediaChangeEvent != NULL) {
2434 
2435  KeSetEvent(deviceExtension->MediaChangeEvent,
2436  (KPRIORITY) 0,
2437  FALSE);
2438  DebugPrint((0, "ScsiClassInterpretSenseInfo:"
2439  "New Media Found - Setting MediaChanged event"
2440  " [irp = 0x%lx]\n", Srb->OriginalRequest));
2441  deviceExtension->MediaChangeNoMedia = FALSE;
2442 
2443  }
2444  break;
2445 
2447  DebugPrint((1,"ScsiClassInterpretSenseInfo: Bus reset\n"));
2448  break;
2449 
2450  default:
2451  DebugPrint((1,"ScsiClassInterpretSenseInfo: Unit attention\n"));
2452  break;
2453 
2454  } // end switch (senseBuffer->AdditionalSenseCode)
2455 
2456  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA &&
2457  DeviceObject->Vpb->Flags & VPB_MOUNTED) {
2458 
2459  //
2460  // Set bit to indicate that media may have changed
2461  // and volume needs verification.
2462  //
2463 
2464  DeviceObject->Flags |= DO_VERIFY_VOLUME;
2465 
2467  retry = FALSE;
2468 
2469  } else {
2470 
2472 
2473  }
2474 
2475  //
2476  // A media change may have occured so increment the change
2477  // count for the physical device
2478  //
2479 
2480  physicalExtension->MediaChangeCount++;
2481 
2482  DebugPrint((2, "ScsiClassInterpretSenseInfo - Media change "
2483  "count for device %d is %d\n",
2484  physicalExtension->DeviceNumber,
2485  physicalExtension->MediaChangeCount));
2486 
2487  break;
2488 
2490 
2491  DebugPrint((1,"ScsiClassInterpretSenseInfo: Command aborted\n"));
2493  break;
2494 
2496 
2497  DebugPrint((1,"ScsiClassInterpretSenseInfo: Recovered error\n"));
2499  retry = FALSE;
2500  logError = TRUE;
2501  uniqueId = 258;
2502 
2503  switch(senseBuffer->AdditionalSenseCode) {
2506  logStatus = 0;//IO_ERR_SEEK_ERROR;
2507  break;
2508 
2511  logStatus = 0;//IO_RECOVERED_VIA_ECC;
2512  break;
2513 
2514  default:
2515  logStatus = 0;//IO_ERR_CONTROLLER_ERROR;
2516  break;
2517 
2518  } // end switch(senseBuffer->AdditionalSenseCode)
2519 
2520  if (senseBuffer->IncorrectLength) {
2521 
2522  DebugPrint((1, "ScsiClassInterpretSenseInfo: Incorrect length detected.\n"));
2524  }
2525 
2526  break;
2527 
2528  case SCSI_SENSE_NO_SENSE:
2529 
2530  //
2531  // Check other indicators.
2532  //
2533 
2534  if (senseBuffer->IncorrectLength) {
2535 
2536  DebugPrint((1, "ScsiClassInterpretSenseInfo: Incorrect length detected.\n"));
2538  retry = FALSE;
2539 
2540  } else {
2541 
2542  DebugPrint((1, "ScsiClassInterpretSenseInfo: No specific sense key\n"));
2544  retry = TRUE;
2545  }
2546 
2547  break;
2548 
2549  default:
2550 
2551  DebugPrint((1, "ScsiClassInterpretSenseInfo: Unrecognized sense code\n"));
2553  break;
2554 
2555  } // end switch (senseBuffer->SenseKey & 0xf)
2556 
2557  //
2558  // Try to determine the bad sector from the inquiry data.
2559  //
2560 
2561  if ((((PCDB)Srb->Cdb)->CDB10.OperationCode == SCSIOP_READ ||
2562  ((PCDB)Srb->Cdb)->CDB10.OperationCode == SCSIOP_VERIFY ||
2563  ((PCDB)Srb->Cdb)->CDB10.OperationCode == SCSIOP_WRITE)) {
2564 
2565  for (index = 0; index < 4; index++) {
2566  badSector = (badSector << 8) | senseBuffer->Information[index];
2567  }
2568 
2569  readSector = 0;
2570  for (index = 0; index < 4; index++) {
2571  readSector = (readSector << 8) | Srb->Cdb[index+2];
2572  }
2573 
2574  index = (((PCDB)Srb->Cdb)->CDB10.TransferBlocksMsb << 8) |
2575  ((PCDB)Srb->Cdb)->CDB10.TransferBlocksLsb;
2576 
2577  //
2578  // Make sure the bad sector is within the read sectors.
2579  //
2580 
2581  if (!(badSector >= readSector && badSector < readSector + index)) {
2582  badSector = readSector;
2583  }
2584  }
2585 
2586  } else {
2587 
2588  //
2589  // Request sense buffer not valid. No sense information
2590  // to pinpoint the error. Return general request fail.
2591  //
2592 
2593  DebugPrint((1,"ScsiClassInterpretSenseInfo: Request sense info not valid. SrbStatus %2x\n",
2594  SRB_STATUS(Srb->SrbStatus)));
2595  retry = TRUE;
2596 
2597  switch (SRB_STATUS(Srb->SrbStatus)) {
2600  case SRB_STATUS_NO_DEVICE:
2601  case SRB_STATUS_NO_HBA:
2604  retry = FALSE;
2605  break;
2606 
2608  case SRB_STATUS_ABORTED:
2609  case SRB_STATUS_TIMEOUT:
2610 
2611  //
2612  // Update the error count for the device.
2613  //
2614 
2615  deviceExtension->ErrorCount++;
2617  break;
2618 
2620  logError = TRUE;
2621  logStatus = 0;//IO_ERR_NOT_READY;
2622  uniqueId = 260;
2624  retry = FALSE;
2625  break;
2626 
2629  retry = FALSE;
2630  break;
2631 
2633 
2634  //
2635  // Update the error count for the device.
2636  //
2637 
2638  deviceExtension->ErrorCount++;
2640 
2641  //
2642  // If there was phase sequence error then limit the number of
2643  // retries.
2644  //
2645 
2646  if (RetryCount > 1 ) {
2647  retry = FALSE;
2648  }
2649 
2650  break;
2651 
2653 
2654  //
2655  // If the status needs verification bit is set. Then set
2656  // the status to need verification and no retry; otherwise,
2657  // just retry the request.
2658  //
2659 
2660  if (DeviceObject->Flags & DO_VERIFY_VOLUME ) {
2661 
2663  retry = FALSE;
2664  } else {
2666  }
2667 
2668  break;
2669 
2671 
2672  //
2673  // An invalid request was attempted.
2674  //
2675 
2677  retry = FALSE;
2678  break;
2679 
2682 
2683  //
2684  // Update the error count for the device.
2685  //
2686 
2687  deviceExtension->ErrorCount++;
2688 
2689  //
2690  // Fall through to below.
2691  //
2692 
2693  case SRB_STATUS_BUS_RESET:
2695  break;
2696 
2697  case SRB_STATUS_ERROR:
2698 
2700  if (Srb->ScsiStatus == 0) {
2701 
2702  //
2703  // This is some strange return code. Update the error
2704  // count for the device.
2705  //
2706 
2707  deviceExtension->ErrorCount++;
2708 
2709  } if (Srb->ScsiStatus == SCSISTAT_BUSY) {
2710 
2712 
2713  } if (Srb->ScsiStatus == SCSISTAT_RESERVATION_CONFLICT) {
2714 
2716  retry = FALSE;
2717 
2718  }
2719 
2720  break;
2721 
2722  default:
2723  logError = TRUE;
2724  logStatus = 0;//IO_ERR_CONTROLLER_ERROR;
2725  uniqueId = 259;
2727  break;
2728 
2729  }
2730 
2731  //
2732  // If the error count has exceeded the error limit, then disable
2733  // any tagged queuing, multiple requests per lu queueing
2734  // and synchronous data transfers.
2735  //
2736 
2737  if (deviceExtension->ErrorCount == 4) {
2738 
2739  //
2740  // Clearing the no queue freeze flag prevents the port driver
2741  // from sending multiple requests per logical unit.
2742  //
2743 
2744  deviceExtension->SrbFlags &= ~(SRB_FLAGS_QUEUE_ACTION_ENABLE |
2746 
2747  deviceExtension->SrbFlags |= SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
2748  DebugPrint((1, "ScsiClassInterpretSenseInfo: Too many errors disabling tagged queuing and synchronous data tranfers.\n"));
2749 
2750  } else if (deviceExtension->ErrorCount == 8) {
2751 
2752  //
2753  // If a second threshold is reached, disable disconnects.
2754  //
2755 
2756  deviceExtension->SrbFlags |= SRB_FLAGS_DISABLE_DISCONNECT;
2757  DebugPrint((1, "ScsiClassInterpretSenseInfo: Too many errors disabling disconnects.\n"));
2758  }
2759  }
2760 
2761  //
2762  // If there is a class specific error handler call it.
2763  //
2764 
2765  if (deviceExtension->ClassError != NULL) {
2766 
2767  deviceExtension->ClassError(DeviceObject,
2768  Srb,
2769  Status,
2770  &retry);
2771  }
2772 
2773  //
2774  // Log an error if necessary.
2775  //
2776 
2777  if (logError) {
2778 
2780  DeviceObject,
2781  sizeof(IO_ERROR_LOG_PACKET) + 5 * sizeof(ULONG));
2782 
2783  if (errorLogEntry == NULL) {
2784 
2785  //
2786  // Return if no packet could be allocated.
2787  //
2788 
2789  return retry;
2790 
2791  }
2792 
2793  if (retry && RetryCount < MAXIMUM_RETRIES) {
2794  errorLogEntry->FinalStatus = STATUS_SUCCESS;
2795  } else {
2796  errorLogEntry->FinalStatus = *Status;
2797  }
2798 
2799  //
2800  // Calculate the device offset if there is a geometry.
2801  //
2802 
2803  if (deviceExtension->DiskGeometry != NULL) {
2804 
2805  errorLogEntry->DeviceOffset.QuadPart = (LONGLONG) badSector;
2806  errorLogEntry->DeviceOffset = RtlExtendedIntegerMultiply(
2807  errorLogEntry->DeviceOffset,
2808  deviceExtension->DiskGeometry->Geometry.BytesPerSector);
2809  }
2810 
2811  errorLogEntry->ErrorCode = logStatus;
2812  errorLogEntry->SequenceNumber = 0;
2813  errorLogEntry->MajorFunctionCode = MajorFunctionCode;
2814  errorLogEntry->IoControlCode = IoDeviceCode;
2815  errorLogEntry->RetryCount = (UCHAR) RetryCount;
2816  errorLogEntry->UniqueErrorValue = uniqueId;
2817  errorLogEntry->DumpDataSize = 6 * sizeof(ULONG);
2818  errorLogEntry->DumpData[0] = Srb->PathId;
2819  errorLogEntry->DumpData[1] = Srb->TargetId;
2820  errorLogEntry->DumpData[2] = Srb->Lun;
2821  errorLogEntry->DumpData[3] = 0;
2822  errorLogEntry->DumpData[4] = Srb->SrbStatus << 8 | Srb->ScsiStatus;
2823 
2824  if (senseBuffer != NULL) {
2825  errorLogEntry->DumpData[5] = senseBuffer->SenseKey << 16 |
2826  senseBuffer->AdditionalSenseCode << 8 |
2827  senseBuffer->AdditionalSenseCodeQualifier;
2828 
2829  }
2830 
2831  //
2832  // Write the error log packet.
2833  //
2834 
2835  IoWriteErrorLogEntry(errorLogEntry);
2836  }
2837 
2838  return retry;
2839 
2840 } // end ScsiClassInterpretSenseInfo()
#define SRB_STATUS_INVALID_REQUEST
Definition: srb.h:338
#define SRB_STATUS_BUS_RESET
Definition: srb.h:345
#define SCSI_SENSEQ_FORMAT_IN_PROGRESS
Definition: cdrw_hw.h:1316
UCHAR SenseKey
Definition: cdrw_hw.h:1167
#define SCSISTAT_BUSY
Definition: cdrw_hw.h:1081
#define STATUS_NO_MEDIA_IN_DEVICE
Definition: udferr_usr.h:141
#define STATUS_DATA_OVERRUN
Definition: udferr_usr.h:152
#define SRB_STATUS_AUTOSENSE_VALID
Definition: srb.h:379
NTSTATUS FinalStatus
Definition: iotypes.h:1989
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:396
#define TRUE
Definition: types.h:120
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
#define SRB_STATUS_REQUEST_FLUSHED
Definition: srb.h:353
#define DO_VERIFY_VOLUME
Definition: env_spec_w32.h:393
#define SCSI_ADSENSE_MUSIC_AREA
Definition: cdrw_hw.h:1282
#define SCSI_ADSENSE_DATA_AREA
Definition: cdrw_hw.h:1283
#define SRB_STATUS_COMMAND_TIMEOUT
Definition: srb.h:343
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define SRB_STATUS_NO_DEVICE
Definition: srb.h:340
#define SRB_STATUS_PHASE_SEQUENCE_FAILURE
Definition: srb.h:351
#define SCSI_ADSENSE_LUN_NOT_READY
Definition: cdrw_hw.h:1218
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
#define SCSI_SENSE_NOT_READY
Definition: cdrw_hw.h:1189
#define SRB_STATUS_INVALID_TARGET_ID
Definition: srb.h:355
#define SRB_STATUS(Status)
Definition: srb.h:381
#define STATUS_INVALID_BLOCK_LENGTH
Definition: udferr_usr.h:175
VOID NTAPI IoWriteErrorLogEntry(IN PVOID ElEntry)
Definition: error.c:628
LONG KPRIORITY
Definition: compat.h:551
LARGE_INTEGER DeviceOffset
Definition: iotypes.h:1992
#define STATUS_NONEXISTENT_SECTOR
Definition: udferr_usr.h:143
#define DEV_WRITE_CACHE
Definition: class2.h:21
#define SCSI_ADSENSE_VOLUME_OVERFLOW
Definition: cdrw_hw.h:1284
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define SRB_STATUS_ERROR
Definition: srb.h:336
#define SCSI_SENSE_MEDIUM_ERROR
Definition: cdrw_hw.h:1190
#define MAXIMUM_RETRIES
Definition: cdrom.h:124
NTSTATUS ErrorCode
Definition: iotypes.h:1987
#define SCSI_ADSENSE_REC_DATA_NOECC
Definition: cdrw_hw.h:1211
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 SRB_STATUS_PARITY_ERROR
Definition: srb.h:346
#define SCSI_SENSEQ_MANUAL_INTERVENTION_REQUIRED
Definition: cdrw_hw.h:1315
#define FALSE
Definition: types.h:117
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define SCSIOP_READ
Definition: cdrw_hw.h:905
#define SCSI_ADSENSE_NO_MEDIA_IN_DEVICE
Definition: cdrw_hw.h:1221
#define SCSIOP_WRITE
Definition: cdrw_hw.h:906
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define SRB_STATUS_NO_HBA
Definition: srb.h:348
#define SRB_STATUS_ABORTED
Definition: srb.h:334
union _CDB * PCDB
#define STATUS_MEDIA_WRITE_PROTECTED
Definition: udferr_usr.h:161
GLuint index
Definition: glext.h:6031
UCHAR Information[4]
Definition: cdrw_hw.h:1172
#define DEV_SAFE_START_UNIT
Definition: cdrom.h:139
_In_ UCHAR _Out_opt_ PUCHAR _Out_opt_ PUCHAR _Out_opt_ PUCHAR AdditionalSenseCodeQualifier
Definition: scsi.h:3748
#define STATUS_DEVICE_NOT_CONNECTED
Definition: udferr_usr.h:160
PVOID NTAPI IoAllocateErrorLogEntry(IN PVOID IoObject, IN UCHAR EntrySize)
Definition: error.c:528
UCHAR AdditionalSenseCodeQualifier
Definition: cdrw_hw.h:1176
int64_t LONGLONG
Definition: typedefs.h:68
#define SCSI_ADSENSE_SEEK_ERROR
Definition: cdrw_hw.h:1232
#define SCSI_ADSENSE_ILLEGAL_BLOCK
Definition: cdrw_hw.h:1264
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define SCSI_SENSEQ_BECOMING_READY
Definition: cdrw_hw.h:1313
#define STATUS_NO_SUCH_DEVICE
Definition: udferr_usr.h:136
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
#define SCSI_ADSENSE_REC_DATA_ECC
Definition: cdrw_hw.h:1212
#define SCSISTAT_RESERVATION_CONFLICT
Definition: cdrw_hw.h:1084
_In_opt_ PIRP _In_ PSCSI_REQUEST_BLOCK _In_ UCHAR MajorFunctionCode
Definition: classpnp.h:482
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:349
NTSYSAPI LONGLONG WINAPI RtlExtendedIntegerMultiply(LONGLONG, INT)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define SCSIOP_VERIFY
Definition: cdrw_hw.h:912
#define SCSI_SENSE_HARDWARE_ERROR
Definition: cdrw_hw.h:1191
#define SRB_FLAGS_DISABLE_DISCONNECT
Definition: srb.h:388
unsigned char UCHAR
Definition: xmlstorage.h:181
Status
Definition: gdiplustypes.h:24
#define index(s, c)
Definition: various.h:29
#define SCSI_ADSENSE_BUS_RESET
Definition: cdrw_hw.h:1289
#define SRB_STATUS_SELECTION_TIMEOUT
Definition: srb.h:342
#define SCSI_SENSE_RECOVERED_ERROR
Definition: cdrw_hw.h:1188
#define SCSI_SENSE_ABORTED_COMMAND
Definition: cdrw_hw.h:1198
#define SCSI_SENSE_NO_SENSE
Definition: cdrw_hw.h:1187
#define SRB_STATUS_INVALID_LUN
Definition: srb.h:354
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define SCSI_SENSEQ_INIT_COMMAND_REQUIRED
Definition: cdrw_hw.h:1314
VOID NTAPI StartUnit(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:1082
_In_ UCHAR _Out_opt_ PUCHAR _Out_opt_ PUCHAR AdditionalSenseCode
Definition: scsi.h:3744
#define SRB_STATUS_TIMEOUT
Definition: srb.h:341
#define STATUS_DEVICE_BUSY
Definition: udferr_usr.h:129
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
unsigned int * PULONG
Definition: retypes.h:1
UCHAR IncorrectLength
Definition: cdrw_hw.h:1169
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163
struct _IO_ERROR_LOG_PACKET * PIO_ERROR_LOG_PACKET
#define SCSI_ADSENSE_INVALID_LUN
Definition: cdrw_hw.h:1266
#define SCSI_ADSENSE_TRACK_ERROR
Definition: cdrw_hw.h:1231
unsigned int ULONG
Definition: retypes.h:1
#define SRB_STATUS_UNEXPECTED_BUS_FREE
Definition: srb.h:350
#define SCSI_SENSE_DATA_PROTECT
Definition: cdrw_hw.h:1194
UCHAR AdditionalSenseLength
Definition: cdrw_hw.h:1173
#define SRB_STATUS_INVALID_PATH_ID
Definition: srb.h:339
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
UCHAR AdditionalSenseCode
Definition: cdrw_hw.h:1175
#define SCSI_SENSE_ILLEGAL_REQUEST
Definition: cdrw_hw.h:1192
#define SCSI_ADSENSE_ILLEGAL_COMMAND
Definition: cdrw_hw.h:1263
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define VPB_MOUNTED
Definition: iotypes.h:1787
#define SCSI_SENSE_UNIT_ATTENTION
Definition: cdrw_hw.h:1193
UCHAR ErrorCode
Definition: cdrw_hw.h:1164
#define SCSI_ADSENSE_INVALID_CDB
Definition: cdrw_hw.h:1265
#define STATUS_DEVICE_DATA_ERROR
Definition: udferr_usr.h:159
#define SRB_FLAGS_QUEUE_ACTION_ENABLE
Definition: srb.h:387
_In_opt_ PIRP _In_ PSCSI_REQUEST_BLOCK _In_ UCHAR _In_ ULONG IoDeviceCode
Definition: classpnp.h:482
LONGLONG QuadPart
Definition: typedefs.h:114
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70
#define SCSI_ADSENSE_MEDIUM_CHANGED
Definition: cdrw_hw.h:1288

Referenced by CdRomDeviceControlCompletion(), CdRomSetVolumeIntermediateCompletion(), CdRomSwitchModeCompletion(), CdRomUpdateGeometryCompletion(), CdRomXACompletion(), ScsiClassIoComplete(), ScsiClassIoCompleteAssociated(), and ScsiClassSendSrbSynchronous().

◆ ScsiClassIoComplete()

NTSTATUS ScsiClassIoComplete ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  Context 
)

Definition at line 1492 of file class2.c.

1523 {
1526  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
1527  NTSTATUS status;
1528  BOOLEAN retry;
1529 
1530  ASSERT(*(PULONG)deviceExtension != '2slc');
1531 
1532  //
1533  // Check SRB status for success of completing request.
1534  //
1535 
1536  if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
1537 
1538  DebugPrint((2,"ScsiClassIoComplete: IRP %lx, SRB %lx\n", Irp, srb));
1539 
1540  //
1541  // Release the queue if it is frozen.
1542  //
1543 
1544  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
1546  }
1547 
1549  DeviceObject,
1550  srb,
1551  irpStack->MajorFunction,
1552  irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL ? irpStack->Parameters.DeviceIoControl.IoControlCode : 0,
1553  MAXIMUM_RETRIES - PtrToUlong(irpStack->Parameters.Others.Argument4),
1554  &status);
1555 
1556  //
1557  // If the status is verified required and the this request
1558  // should bypass verify required then retry the request.
1559  //
1560 
1561  if (irpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME &&
1563 
1565  retry = TRUE;
1566  }
1567 
1568  if (retry && (irpStack->Parameters.Others.Argument4 = (PVOID)((ULONG_PTR)irpStack->Parameters.Others.Argument4-1))) {
1569 
1570  //
1571  // Retry request.
1572  //
1573 
1574  DebugPrint((1, "Retry request %lx\n", Irp));
1577  }
1578  } else {
1579 
1580  //
1581  // Set status for successful request.
1582  //
1583 
1585 
1586  } // end if (SRB_STATUS(srb->SrbStatus) ...
1587 
1588  //
1589  // Return SRB to list.
1590  //
1591 
1592  ExFreeToNPagedLookasideList(&deviceExtension->SrbLookasideListHead,
1593  srb);
1594 
1595  //
1596  // Set status in completing IRP.
1597  //
1598 
1599  Irp->IoStatus.Status = status;
1600  if ((NT_SUCCESS(status)) && (Irp->Flags & IRP_PAGING_IO)) {
1601  ASSERT(Irp->IoStatus.Information);
1602  }
1603 
1604  //
1605  // Set the hard error if necessary.
1606  //
1607 
1609 
1610  //
1611  // Store DeviceObject for filesystem, and clear
1612  // in IoStatus.Information field.
1613  //
1614 
1616  Irp->IoStatus.Information = 0;
1617  }
1618 
1619  //
1620  // If pending has be returned for this irp then mark the current stack as
1621  // pending.
1622  //
1623 
1624  if (Irp->PendingReturned) {
1626  }
1627 
1628  if (deviceExtension->ClassStartIo) {
1629  if (irpStack->MajorFunction != IRP_MJ_DEVICE_CONTROL) {
1631  }
1632  }
1633 
1634  return status;
1635 
1636 } // end ScsiClassIoComplete()
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2813
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI RetryRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp, PSCSI_REQUEST_BLOCK Srb, BOOLEAN Associated)
Definition: class2.c:2845
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
UCHAR SrbStatus
Definition: srb.h:243
#define SRB_STATUS(Status)
Definition: srb.h:381
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define MAXIMUM_RETRIES
Definition: cdrom.h:124
#define FALSE
Definition: types.h:117
VOID NTAPI ScsiClassReleaseQueue(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:939
unsigned char BOOLEAN
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1803
#define PtrToUlong(u)
Definition: config.h:107
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:378
BOOLEAN NTAPI ScsiClassInterpretSenseInfo(IN PDEVICE_OBJECT DeviceObject, IN PSCSI_REQUEST_BLOCK Srb, IN UCHAR MajorFunctionCode, IN ULONG IoDeviceCode, IN ULONG RetryCount, OUT NTSTATUS *Status)
Definition: class2.c:2148
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
unsigned int * PULONG
Definition: retypes.h:1
#define IRP_PAGING_IO
struct tagContext Context
Definition: acpixf.h:1034
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
IoMarkIrpPending(Irp)
static SERVICE_STATUS status
Definition: service.c:31
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
VOID NTAPI IoStartNextPacket(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable)
Definition: device.c:1847
Definition: ps.c:97

Referenced by RetryRequest(), ScsiClassBuildRequest(), ScsiClassSendSrbAsynchronous(), and ScsiDiskShutdownFlush().

◆ ScsiClassIoCompleteAssociated()

NTSTATUS ScsiClassIoCompleteAssociated ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PVOID  Context 
)

Definition at line 1641 of file class2.c.

1675 {
1678  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
1679  PIRP originalIrp = Irp->AssociatedIrp.MasterIrp;
1680  LONG irpCount;
1681  NTSTATUS status;
1682  BOOLEAN retry;
1683 
1684  ASSERT(*(PULONG)deviceExtension != '2slc');
1685 
1686  //
1687  // Check SRB status for success of completing request.
1688  //
1689 
1690  if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
1691 
1692  DebugPrint((2,"ScsiClassIoCompleteAssociated: IRP %lx, SRB %lx", Irp, srb));
1693 
1694  //
1695  // Release the queue if it is frozen.
1696  //
1697 
1698  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
1700  }
1701 
1703  DeviceObject,
1704  srb,
1705  irpStack->MajorFunction,
1706  irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL ? irpStack->Parameters.DeviceIoControl.IoControlCode : 0,
1707  MAXIMUM_RETRIES - PtrToUlong(irpStack->Parameters.Others.Argument4),
1708  &status);
1709 
1710  //
1711  // If the status is verified required and the this request
1712  // should bypass verify required then retry the request.
1713  //
1714 
1715  if (irpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME &&
1717 
1719  retry = TRUE;
1720  }
1721 
1722  if (retry && (irpStack->Parameters.Others.Argument4 = (PVOID)((ULONG_PTR)irpStack->Parameters.Others.Argument4-1))) {
1723 
1724  //
1725  // Retry request. If the class driver has supplied a StartIo,
1726  // call it directly for retries.
1727  //
1728 
1729  DebugPrint((1, "Retry request %lx\n", Irp));
1730 
1731  /*
1732  if (!deviceExtension->ClassStartIo) {
1733  RetryRequest(DeviceObject, Irp, srb, TRUE);
1734  } else {
1735  deviceExtension->ClassStartIo(DeviceObject, Irp);
1736  }
1737  */
1738 
1740 
1742  }
1743 
1744 
1745 
1746  } else {
1747 
1748  //
1749  // Set status for successful request.
1750  //
1751 
1753 
1754  } // end if (SRB_STATUS(srb->SrbStatus) ...
1755 
1756  //
1757  // Return SRB to list.
1758  //
1759 
1760  ExFreeToNPagedLookasideList(&deviceExtension->SrbLookasideListHead,
1761  srb);
1762 
1763  //
1764  // Set status in completing IRP.
1765  //
1766 
1767  Irp->IoStatus.Status = status;
1768 
1769  DebugPrint((2, "ScsiClassIoCompleteAssociated: Partial xfer IRP %lx\n", Irp));
1770 
1771  //
1772  // Get next stack location. This original request is unused
1773  // except to keep track of the completing partial IRPs so the
1774  // stack location is valid.
1775  //
1776 
1777  irpStack = IoGetNextIrpStackLocation(originalIrp);
1778 
1779  //
1780  // Update status only if error so that if any partial transfer
1781  // completes with error, then the original IRP will return with
1782  // error. If any of the asynchronous partial transfer IRPs fail,
1783  // with an error then the original IRP will return 0 bytes transfered.
1784  // This is an optimization for successful transfers.
1785  //
1786 
1787  if (!NT_SUCCESS(status)) {
1788 
1789  originalIrp->IoStatus.Status = status;
1790  originalIrp->IoStatus.Information = 0;
1791 
1792  //
1793  // Set the hard error if necessary.
1794  //
1795 
1797 
1798  //
1799  // Store DeviceObject for filesystem.
1800  //
1801 
1803  }
1804  }
1805 
1806  //
1807  // Decrement and get the count of remaining IRPs.
1808  //
1809 
1810  irpCount = InterlockedDecrement((PLONG)&irpStack->Parameters.Others.Argument1);
1811 
1812  DebugPrint((2, "ScsiClassIoCompleteAssociated: Partial IRPs left %d\n",
1813  irpCount));
1814 
1815  //
1816  // Old bug could cause irp count to negative
1817  //
1818 
1819  ASSERT(irpCount >= 0);
1820 
1821  if (irpCount == 0) {
1822 
1823  //
1824  // All partial IRPs have completed.
1825  //
1826 
1827  DebugPrint((2,
1828  "ScsiClassIoCompleteAssociated: All partial IRPs complete %lx\n",
1829  originalIrp));
1830 
1831  IoCompleteRequest(originalIrp, IO_DISK_INCREMENT);
1832 
1833  //
1834  // If the class driver has supplied a startio, start the
1835  // next request.
1836  //
1837 
1838  if (deviceExtension->ClassStartIo) {
1840  }
1841  }
1842 
1843  //
1844  // Deallocate IRP and indicate the I/O system should not attempt any more
1845  // processing.
1846  //
1847 
1848  IoFreeIrp(Irp);
1850 
1851 } // end ScsiClassIoCompleteAssociated()
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2813
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI RetryRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp, PSCSI_REQUEST_BLOCK Srb, BOOLEAN Associated)
Definition: class2.c:2845
IO_STATUS_BLOCK IoStatus
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
UCHAR SrbStatus
Definition: srb.h:243
#define SRB_STATUS(Status)
Definition: srb.h:381
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define MAXIMUM_RETRIES
Definition: cdrom.h:124
#define IO_DISK_INCREMENT
Definition: iotypes.h:583
#define FALSE
Definition: types.h:117
VOID NTAPI ScsiClassReleaseQueue(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:939
long LONG
Definition: pedump.c:60
unsigned char BOOLEAN
#define IoCompleteRequest
Definition: irp.c:1240
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1803
#define PtrToUlong(u)
Definition: config.h:107
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:378
#define InterlockedDecrement
Definition: armddk.h:52
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
BOOLEAN NTAPI ScsiClassInterpretSenseInfo(IN PDEVICE_OBJECT DeviceObject, IN PSCSI_REQUEST_BLOCK Srb, IN UCHAR MajorFunctionCode, IN ULONG IoDeviceCode, IN ULONG RetryCount, OUT NTSTATUS *Status)
Definition: class2.c:2148
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
unsigned int * PULONG
Definition: retypes.h:1
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
struct tagContext Context
Definition: acpixf.h:1034
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
VOID NTAPI IoSetHardErrorOrVerifyDevice(IN PIRP Irp, IN PDEVICE_OBJECT DeviceObject)
Definition: util.c:316
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
signed int * PLONG
Definition: retypes.h:5
static SERVICE_STATUS status
Definition: service.c:31
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
VOID NTAPI IoStartNextPacket(IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN Cancelable)
Definition: device.c:1847
Definition: ps.c:97

Referenced by RetryRequest(), and ScsiClassSplitRequest().

◆ ScsiClassModeSelect()

BOOLEAN ScsiClassModeSelect ( IN PDEVICE_OBJECT  DeviceObject,
IN PCHAR  ModeSelectBuffer,
IN ULONG  Length,
IN BOOLEAN  SavePage 
)

◆ ScsiClassModeSense()

ULONG ScsiClassModeSense ( IN PDEVICE_OBJECT  DeviceObject,
IN PCHAR  ModeSenseBuffer,
IN ULONG  Length,
IN UCHAR  PageMode 
)

Definition at line 3199 of file class2.c.

3228 {
3229  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3230  PCDB cdb;
3231  SCSI_REQUEST_BLOCK srb;
3232  ULONG retries = 1;
3233  NTSTATUS status;
3234 
3235  ASSERT(*(PULONG)deviceExtension != '2slc');
3236 
3237  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
3238 
3239  //
3240  // Build the MODE SENSE CDB.
3241  //
3242 
3243  srb.CdbLength = 6;
3244  cdb = (PCDB)srb.Cdb;
3245 
3246  //
3247  // Set timeout value from device extension.
3248  //
3249 
3250  srb.TimeOutValue = deviceExtension->TimeOutValue;
3251 
3252  cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
3253  cdb->MODE_SENSE.PageCode = PageMode;
3254  cdb->MODE_SENSE.AllocationLength = (UCHAR)Length;
3255 
3256 Retry:
3257 
3259  &srb,
3260  ModeSenseBuffer,
3261  Length,
3262  FALSE);
3263 
3264 
3265  if (status == STATUS_VERIFY_REQUIRED) {
3266 
3267  //
3268  // Routine ScsiClassSendSrbSynchronous does not retry requests returned with
3269  // this status. MODE SENSE commands should be retried anyway.
3270  //
3271 
3272  if (retries--) {
3273 
3274  //
3275  // Retry request.
3276  //
3277 
3278  goto Retry;
3279  }
3280 
3281  } else if (SRB_STATUS(srb.SrbStatus) == SRB_STATUS_DATA_OVERRUN) {
3283  }
3284 
3285  if (NT_SUCCESS(status)) {
3286  return(srb.DataTransferLength);
3287  } else {
3288  return(0);
3289  }
3290 
3291 } // end ScsiClassModeSense()
_In_ size_t _In_ UCHAR PageMode
Definition: cdrom.h:1325
UCHAR Cdb[16]
Definition: srb.h:271
#define SCSIOP_MODE_SENSE
Definition: cdrw_hw.h:896
ULONG DataTransferLength
Definition: srb.h:253
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
UCHAR CdbLength
Definition: srb.h:250
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
ULONG TimeOutValue
Definition: srb.h:254
UCHAR SrbStatus
Definition: srb.h:243
#define SRB_STATUS(Status)
Definition: srb.h:381
#define FALSE
Definition: types.h:117
union _CDB * PCDB
IN PSCSI_REQUEST_BLOCK IN OUT NTSTATUS IN OUT BOOLEAN * Retry
Definition: class2.h:49
struct _CDB::_MODE_SENSE MODE_SENSE
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:349
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
unsigned char UCHAR
Definition: xmlstorage.h:181
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
unsigned int * PULONG
Definition: retypes.h:1
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
return STATUS_SUCCESS
Definition: btrfs.c:3014
static SERVICE_STATUS status
Definition: service.c:31
NTSTATUS NTAPI ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
Definition: class2.c:1856
Definition: ps.c:97

Referenced by DisableWriteCache(), IsFloppyDevice(), and ScsiDiskDeviceControl().

◆ ScsiClassReadDriveCapacity()

NTSTATUS ScsiClassReadDriveCapacity ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 714 of file class2.c.

736 {
737  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
738  ULONG retries = 1;
739  ULONG lastSector;
740  PCDB cdb;
741  PREAD_CAPACITY_DATA readCapacityBuffer;
742  SCSI_REQUEST_BLOCK srb;
744 
745  ASSERT(*(PULONG)deviceExtension != '2slc');
746 
747  //
748  // Allocate read capacity buffer from nonpaged pool.
749  //
750 
751  readCapacityBuffer = ExAllocatePool(NonPagedPoolCacheAligned,
752  sizeof(READ_CAPACITY_DATA));
753 
754  if (!readCapacityBuffer) {
756  }
757 
758  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
759 
760  //
761  // Build the read capacity CDB.
762  //
763 
764  srb.CdbLength = 10;
765  cdb = (PCDB)srb.Cdb;
766 
767  //
768  // Set timeout value from device extension.
769  //
770 
771  srb.TimeOutValue = deviceExtension->TimeOutValue;
772 
773  cdb->CDB10.OperationCode = SCSIOP_READ_CAPACITY;
774 
775 Retry:
776 
778  &srb,
779  readCapacityBuffer,
780  sizeof(READ_CAPACITY_DATA),
781  FALSE);
782 
783  if (NT_SUCCESS(status)) {
784 
785  //
786  // Copy sector size from read capacity buffer to device extension
787  // in reverse byte order.
788  //
789 
790  ((PFOUR_BYTE)&deviceExtension->DiskGeometry->Geometry.BytesPerSector)->Byte0 =
791  ((PFOUR_BYTE)&readCapacityBuffer->BytesPerBlock)->Byte3;
792 
793  ((PFOUR_BYTE)&deviceExtension->DiskGeometry->Geometry.BytesPerSector)->Byte1 =
794  ((PFOUR_BYTE)&readCapacityBuffer->BytesPerBlock)->Byte2;
795 
796  ((PFOUR_BYTE)&deviceExtension->DiskGeometry->Geometry.BytesPerSector)->Byte2 =
797  ((PFOUR_BYTE)&readCapacityBuffer->BytesPerBlock)->Byte1;
798 
799  ((PFOUR_BYTE)&deviceExtension->DiskGeometry->Geometry.BytesPerSector)->Byte3 =
800  ((PFOUR_BYTE)&readCapacityBuffer->BytesPerBlock)->Byte0;
801 
802  //
803  // Copy last sector in reverse byte order.
804  //
805 
806  ((PFOUR_BYTE)&lastSector)->Byte0 =
807  ((PFOUR_BYTE)&readCapacityBuffer->LogicalBlockAddress)->Byte3;
808 
809  ((PFOUR_BYTE)&lastSector)->Byte1 =
810  ((PFOUR_BYTE)&readCapacityBuffer->LogicalBlockAddress)->Byte2;
811 
812  ((PFOUR_BYTE)&lastSector)->Byte2 =
813  ((PFOUR_BYTE)&readCapacityBuffer->LogicalBlockAddress)->Byte1;
814 
815  ((PFOUR_BYTE)&lastSector)->Byte3 =
816  ((PFOUR_BYTE)&readCapacityBuffer->LogicalBlockAddress)->Byte0;
817 
818  //
819  // Calculate sector to byte shift.
820  //
821 
822  WHICH_BIT(deviceExtension->DiskGeometry->Geometry.BytesPerSector, deviceExtension->SectorShift);
823 
824  DebugPrint((2,"SCSI ScsiClassReadDriveCapacity: Sector size is %d\n",
825  deviceExtension->DiskGeometry->Geometry.BytesPerSector));
826 
827  DebugPrint((2,"SCSI ScsiClassReadDriveCapacity: Number of Sectors is %d\n",
828  lastSector + 1));
829 
830  //
831  // Calculate number of cylinders.
832  //
833 
834  deviceExtension->DiskGeometry->Geometry.Cylinders.QuadPart = (LONGLONG)((lastSector + 1)/(DEFAULT_SECTORS_PER_TRACK * DEFAULT_TRACKS_PER_CYLINDER));
835 
836  //
837  // Calculate media capacity in bytes.
838  //
839 
840  deviceExtension->PartitionLength.QuadPart = (LONGLONG)(lastSector + 1);
841  deviceExtension->PartitionLength.QuadPart =
842  (deviceExtension->PartitionLength.QuadPart << deviceExtension->SectorShift);
843  deviceExtension->DiskGeometry->DiskSize.QuadPart = deviceExtension->PartitionLength.QuadPart;
844 
845  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
846 
847  //
848  // This device supports removable media.
849  //
850 
851  deviceExtension->DiskGeometry->Geometry.MediaType = RemovableMedia;
852 
853  } else {
854 
855  //
856  // Assume media type is fixed disk.
857  //
858 
859  deviceExtension->DiskGeometry->Geometry.MediaType = FixedMedia;
860  }
861 
862  //
863  // Assume sectors per track are DEFAULT_SECTORS_PER_TRACK;
864  //
865 
866  deviceExtension->DiskGeometry->Geometry.SectorsPerTrack = DEFAULT_SECTORS_PER_TRACK;
867 
868  //
869  // Assume tracks per cylinder (number of heads) is DEFAULT_TRACKS_PER_CYLINDER.
870  //
871 
872  deviceExtension->DiskGeometry->Geometry.TracksPerCylinder = DEFAULT_TRACKS_PER_CYLINDER;
873  }
874 
876 
877  //
878  // Routine ScsiClassSendSrbSynchronous does not retry
879  // requests returned with this status.
880  // Read Capacities should be retried
881  // anyway.
882  //
883 
884  if (retries--) {
885 
886  //
887  // Retry request.
888  //
889 
890  goto Retry;
891  }
892  }
893 
894  if (!NT_SUCCESS(status)) {
895 
896  //
897  // If the read capacity fails, set the geometry to reasonable parameter
898  // so things don't fail at unexpected places. Zero the geometry
899  // except for the bytes per sector and sector shift.
900  //
901 
902  RtlZeroMemory(deviceExtension->DiskGeometry, sizeof(DISK_GEOMETRY_EX));
903  deviceExtension->DiskGeometry->Geometry.BytesPerSector = 512;
904  deviceExtension->SectorShift = 9;
905  deviceExtension->PartitionLength.QuadPart = (LONGLONG) 0;
906  deviceExtension->DiskGeometry->DiskSize.QuadPart = (LONGLONG) 0;
907 
908  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
909 
910  //
911  // This device supports removable media.
912  //
913 
914  deviceExtension->DiskGeometry->Geometry.MediaType = RemovableMedia;
915 
916  } else {
917 
918  //
919  // Assume media type is fixed disk.
920  //
921 
922  deviceExtension->DiskGeometry->Geometry.MediaType = FixedMedia;
923  }
924  }
925 
926  //
927  // Deallocate read capacity buffer.
928  //
929 
930  ExFreePool(readCapacityBuffer);
931 
932  return status;
933 
934 } // end ScsiClassReadDriveCapacity()
struct _FOUR_BYTE * PFOUR_BYTE
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
UCHAR Cdb[16]
Definition: srb.h:271
Definition: cdrw_hw.h:28
LONG NTSTATUS
Definition: precomp.h:26
UCHAR CdbLength
Definition: srb.h:250
ULONG LogicalBlockAddress
Definition: cdrw_hw.h:1471
struct _CDB::_CDB10 CDB10
#define STATUS_VERIFY_REQUIRED
Definition: udferr_usr.h:130
ULONG TimeOutValue
Definition: srb.h:254
#define WHICH_BIT(Data, Bit)
Definition: tools.h:80
#define FALSE
Definition: types.h:117
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define DEFAULT_SECTORS_PER_TRACK
Definition: class2.c:37
union _CDB * PCDB
IN PSCSI_REQUEST_BLOCK IN OUT NTSTATUS IN OUT BOOLEAN * Retry
Definition: class2.h:49
int64_t LONGLONG
Definition: typedefs.h:68
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
unsigned int * PULONG
Definition: retypes.h:1
#define SCSIOP_READ_CAPACITY
Definition: cdrw_hw.h:904
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
static SERVICE_STATUS status
Definition: service.c:31
NTSTATUS NTAPI ScsiClassSendSrbSynchronous(PDEVICE_OBJECT DeviceObject, PSCSI_REQUEST_BLOCK Srb, PVOID BufferAddress, ULONG BufferLength, BOOLEAN WriteToDevice)
Definition: class2.c:1856
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define DEFAULT_TRACKS_PER_CYLINDER
Definition: class2.c:38
Definition: ps.c:97

◆ ScsiClassReleaseQueue()

VOID ScsiClassReleaseQueue ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 939 of file class2.c.

963 {
964  PIO_STACK_LOCATION irpStack;
965  PIRP irp;
966  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
969  KIRQL currentIrql;
970 
971  ASSERT(*(PULONG)deviceExtension != '2slc');
972 
973  //
974  // Allocate context from nonpaged pool.
975  //
976 
978  sizeof(COMPLETION_CONTEXT));
979 
980  //
981  // Save the device object in the context for use by the completion
982  // routine.
983  //
984 
985  context->DeviceObject = DeviceObject;
986  srb = &context->Srb;
987 
988  //
989  // Zero out srb.
990  //
991 
993 
994  //
995  // Write length to SRB.
996  //
997 
999 
1000  //
1001  // Set up SCSI bus address.
1002  //
1003 
1004  srb->PathId = deviceExtension->PathId;
1005  srb->TargetId = deviceExtension->TargetId;
1006  srb->Lun = deviceExtension->Lun;
1007 
1008  //
1009  // If this device is removable then flush the queue. This will also
1010  // release it.
1011  //
1012 
1013  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
1014 
1016 
1017  } else {
1018 
1020 
1021  }
1022 
1023  //
1024  // Build the asynchronous request to be sent to the port driver.
1025  //
1026 
1027  irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
1028 
1029  if(irp == NULL) {
1030 
1031  //
1032  // We have no better way of dealing with this at the moment
1033  //
1034 
1035  KeBugCheck((ULONG)0x0000002DL);
1036 
1037  }
1038 
1041  context,
1042  TRUE,
1043  TRUE,
1044  TRUE);
1045 
1046  irpStack = IoGetNextIrpStackLocation(irp);
1047 
1048  irpStack->MajorFunction = IRP_MJ_SCSI;
1049 
1050  srb->OriginalRequest = irp;
1051 
1052  //
1053  // Store the SRB address in next stack for port driver.
1054  //
1055 
1056  irpStack->Parameters.Scsi.Srb = srb;
1057 
1058  //
1059  // Since this routine can cause outstanding requests to be completed, and
1060  // calling a completion routine at < DISPATCH_LEVEL is dangerous (if they
1061  // call IoStartNextPacket we will bugcheck) raise up to dispatch level before
1062  // issuing the request
1063  //
1064 
1065  currentIrql = KeGetCurrentIrql();
1066 
1067  if(currentIrql < DISPATCH_LEVEL) {
1068  KeRaiseIrql(DISPATCH_LEVEL, &currentIrql);
1069  IoCallDriver(deviceExtension->PortDeviceObject, irp);
1070  KeLowerIrql(currentIrql);
1071  } else {
1072  IoCallDriver(deviceExtension->PortDeviceObject, irp);
1073  }
1074 
1075  return;
1076 
1077 } // end ScsiClassReleaseQueue()
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
PVOID OriginalRequest
Definition: srb.h:258
Definition: http.c:7094
#define TRUE
Definition: types.h:120
NTSTATUS NTAPI ScsiClassAsynchronousCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
Definition: class2.c:1217
#define SRB_FUNCTION_FLUSH_QUEUE
Definition: srb.h:321
#define SRB_FUNCTION_RELEASE_QUEUE
Definition: srb.h:311
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
#define IRP_MJ_SCSI
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FALSE
Definition: types.h:117
DECLSPEC_NORETURN VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1431
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
smooth NULL
Definition: ftsmooth.c:416
UCHAR TargetId
Definition: srb.h:246
UCHAR Function
Definition: srb.h:242
USHORT Length
Definition: srb.h:241
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
UCHAR PathId
Definition: srb.h:245
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
IO_COMPLETION_ROUTINE * PIO_COMPLETION_ROUTINE
Definition: iotypes.h:2814
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107

Referenced by ScsiClassAsynchronousCompletion(), ScsiClassIoComplete(), ScsiClassIoCompleteAssociated(), and ScsiClassSendSrbSynchronous().

◆ ScsiClassRemoveDevice()

NTSTATUS ScsiClassRemoveDevice ( IN PDEVICE_OBJECT  PortDeviceObject,
IN UCHAR  PathId,
IN UCHAR  TargetId,
IN UCHAR  Lun 
)

◆ ScsiClassSendSrbAsynchronous()

NTSTATUS ScsiClassSendSrbAsynchronous ( PDEVICE_OBJECT  DeviceObject,
PSCSI_REQUEST_BLOCK  Srb,
PIRP  Irp,
PVOID  BufferAddress,
ULONG  BufferLength,
BOOLEAN  WriteToDevice 
)

Definition at line 3370 of file class2.c.

3406 {
3407 
3408  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3409  PIO_STACK_LOCATION irpStack;
3410 
3411  PAGED_CODE();
3412 
3413  ASSERT(*(PULONG)deviceExtension != '2slc');
3414 
3415  //
3416  // Write length to SRB.
3417  //
3418 
3419  Srb->Length = SCSI_REQUEST_BLOCK_SIZE;
3420 
3421  //
3422  // Set SCSI bus address.
3423  //
3424 
3425  Srb->PathId = deviceExtension->PathId;
3426  Srb->TargetId = deviceExtension->TargetId;
3427  Srb->Lun = deviceExtension->Lun;
3428 
3429  Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
3430 
3431  //
3432  // This is a violation of the SCSI spec but it is required for
3433  // some targets.
3434  //
3435 
3436  Srb->Cdb[1] |= deviceExtension->Lun << 5;
3437 
3438  //
3439  // Indicate auto request sense by specifying buffer and size.
3440  //
3441 
3442  Srb->SenseInfoBuffer = deviceExtension->SenseData;
3443  Srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
3444  Srb->DataBuffer = BufferAddress;
3445 
3446  if (BufferAddress != NULL) {
3447 
3448  //
3449  // Build Mdl if necessary.
3450  //
3451 
3452  if (Irp->MdlAddress == NULL) {
3453 
3455  BufferLength,
3456  FALSE,
3457  FALSE,
3458  Irp) == NULL) {
3459 
3461  }
3462 
3463  MmBuildMdlForNonPagedPool(Irp->MdlAddress);
3464 
3465  } else {
3466 
3467  //
3468  // Make sure the buffer requested matches the MDL.
3469  //
3470 
3472  }
3473 
3474  //
3475  // Set read flag.
3476  //
3477 
3479 
3480  } else {
3481 
3482  //
3483  // Clear flags.
3484  //
3485 
3486  Srb->SrbFlags = SRB_FLAGS_NO_DATA_TRANSFER;
3487  }
3488 
3489  //
3490  // Disable synchronous transfer for these requests.
3491  //
3492 
3494 
3495  //
3496  // Set the transfer length.
3497  //
3498 
3499  Srb->DataTransferLength = BufferLength;
3500 
3501  //
3502  // Zero out status.
3503  //
3504 
3505  Srb->ScsiStatus = Srb->SrbStatus = 0;
3506 
3507  Srb->NextSrb = 0;
3508 
3509  //
3510  // Save a few parameters in the current stack location.
3511  //
3512 
3513  irpStack = IoGetCurrentIrpStackLocation(Irp);
3514 
3515  //
3516  // Save retry count in current Irp stack.
3517  //
3518 
3519  irpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
3520 
3521  //
3522  // Set up IoCompletion routine address.
3523  //
3524 
3526 
3527  //
3528  // Get next stack location and
3529  // set major function code.
3530  //
3531 
3532  irpStack = IoGetNextIrpStackLocation(Irp);
3533 
3534  irpStack->MajorFunction = IRP_MJ_SCSI;
3535 
3536  //
3537  // Save SRB address in next stack for port driver.
3538  //
3539 
3540  irpStack->Parameters.Scsi.Srb = Srb;
3541 
3542  //
3543  // Set up Irp Address.
3544  //
3545 
3546  Srb->OriginalRequest = Irp;
3547 
3548  //
3549  // Call the port driver to process the request.
3550  //
3551 
3552  return(IoCallDriver(deviceExtension->PortDeviceObject, Irp));
3553 
3554 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID _In_ ULONG BufferLength
Definition: cdrom.h:989
PVOID OriginalRequest
Definition: srb.h:258
#define MmGetMdlVirtualAddress(_Mdl)
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
VOID NTAPI MmBuildMdlForNonPagedPool(IN PMDL Mdl)
Definition: mdlsup.c:428
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
#define IRP_MJ_SCSI
#define MAXIMUM_RETRIES
Definition: cdrom.h:124
#define FALSE
Definition: types.h:117
UCHAR ScsiStatus
Definition: srb.h:244
smooth NULL
Definition: ftsmooth.c:416
void * PVOID
Definition: retypes.h:9
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
NTSTATUS NTAPI ScsiClassIoComplete(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: class2.c:1492
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define SRB_FLAGS_NO_DATA_TRANSFER
Definition: srb.h:394
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID _In_ ULONG _In_ BOOLEAN WriteToDevice
Definition: cdrom.h:989
PMDL NTAPI IoAllocateMdl(IN PVOID VirtualAddress, IN ULONG Length, IN BOOLEAN SecondaryBuffer, IN BOOLEAN ChargeQuota, IN PIRP Irp)
Definition: iomdl.c:22
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
unsigned int * PULONG
Definition: retypes.h:1
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:393
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID BufferAddress
Definition: cdrom.h:989
#define PAGED_CODE()

Referenced by ScsiClassDeviceControl(), and ScsiDiskDeviceControl().

◆ ScsiClassSendSrbSynchronous()

NTSTATUS ScsiClassSendSrbSynchronous ( PDEVICE_OBJECT  DeviceObject,
PSCSI_REQUEST_BLOCK  Srb,
PVOID  BufferAddress,
ULONG  BufferLength,
BOOLEAN  WriteToDevice 
)

Definition at line 1856 of file class2.c.

1892 {
1893  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
1894  IO_STATUS_BLOCK ioStatus;
1895  ULONG controlType, mjFunction;
1896  PIRP irp;
1897  PIO_STACK_LOCATION irpStack;
1898  KEVENT event;
1900  ULONG retryCount = MAXIMUM_RETRIES;
1901  NTSTATUS status;
1902  BOOLEAN retry;
1904 
1905  PAGED_CODE();
1906 
1907  ASSERT(*(PULONG)deviceExtension != '2slc');
1908 
1909  dummy.QuadPart = 0;
1910 
1911  //
1912  // Write length to SRB.
1913  //
1914 
1915  Srb->Length = SCSI_REQUEST_BLOCK_SIZE;
1916 
1917  //
1918  // Set SCSI bus address.
1919  //
1920 
1921  Srb->PathId = deviceExtension->PathId;
1922  Srb->TargetId = deviceExtension->TargetId;
1923  Srb->Lun = deviceExtension->Lun;
1924  Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
1925 
1926  //
1927  // NOTICE: The SCSI-II specification indicates that this field should be
1928  // zero; however, some target controllers ignore the logical unit number
1929  // in the IDENTIFY message and only look at the logical unit number field
1930  // in the CDB.
1931  //
1932 
1933  Srb->Cdb[1] |= deviceExtension->Lun << 5;
1934 
1935  //
1936  // Enable auto request sense.
1937  //
1938 
1939  Srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
1940 
1941  //
1942  // Sense buffer is in aligned nonpaged pool.
1943  //
1944 
1946 
1947  if (senseInfoBuffer == NULL) {
1948 
1949  DebugPrint((1,
1950  "ScsiClassSendSrbSynchronous: Can't allocate request sense buffer\n"));
1952  }
1953 
1954  Srb->SenseInfoBuffer = senseInfoBuffer;
1955  Srb->DataBuffer = BufferAddress;
1956 
1957  //
1958  // Start retries here.
1959  //
1960 
1961 retry:
1962 
1963  //
1964  // Set the event object to the unsignaled state.
1965  // It will be used to signal request completion.
1966  //
1967 
1969 
1970  //
1971  // Set controlType and Srb direction flags.
1972  //
1973 
1974  if (BufferAddress != NULL) {
1975 
1976  if (WriteToDevice) {
1977 
1978  controlType = IOCTL_SCSI_EXECUTE_OUT;
1979  Srb->SrbFlags = SRB_FLAGS_DATA_OUT;
1980  mjFunction = IRP_MJ_WRITE;
1981 
1982  } else {
1983 
1984  controlType = IOCTL_SCSI_EXECUTE_IN;
1985  Srb->SrbFlags = SRB_FLAGS_DATA_IN;
1986  mjFunction = IRP_MJ_READ;
1987  }
1988 
1989  } else {
1990 
1991  BufferLength = 0;
1992  controlType = IOCTL_SCSI_EXECUTE_NONE;
1993  Srb->SrbFlags = SRB_FLAGS_NO_DATA_TRANSFER;
1994  mjFunction = IRP_MJ_FLUSH_BUFFERS;
1995  }
1996 
1997  //
1998  // Build device I/O control request with data transfer.
1999  //
2001  mjFunction,
2002  deviceExtension->DeviceObject,
2003  BufferAddress,
2004  (BufferAddress) ? BufferLength : 0,
2005  &dummy,
2006  &ioStatus);
2007 
2008  if (irp == NULL) {
2010  DebugPrint((1, "ScsiClassSendSrbSynchronous: Can't allocate Irp\n"));
2012  }
2013 
2014  // Set event field
2015  irp->UserEvent = &event;
2016 
2017  //
2018  // Disable synchronous transfer for these requests.
2019  //
2020 
2022 
2023  //
2024  // Set the transfer length.
2025  //
2026 
2027  Srb->DataTransferLength = BufferLength;
2028 
2029  //
2030  // Zero out status.
2031  //
2032 
2033  Srb->ScsiStatus = Srb->SrbStatus = 0;
2034  Srb->NextSrb = 0;
2035 
2036  // Set completion routine
2038  irp,
2040  NULL,
2041  TRUE,
2042  TRUE,
2043  TRUE);
2044 
2045  //
2046  // Get next stack location.
2047  //
2048 
2049  irpStack = IoGetNextIrpStackLocation(irp);
2050 
2052  irpStack->Parameters.DeviceIoControl.IoControlCode = controlType;
2053 
2054  //
2055  // Set up SRB for execute scsi request. Save SRB address in next stack
2056  // for the port driver.
2057  //
2058 
2059  irpStack->Parameters.Scsi.Srb = Srb;
2060 
2061  //
2062  // Set up IRP Address.
2063  //
2064 
2065  Srb->OriginalRequest = irp;
2066 
2067  //
2068  // Call the port driver with the request and wait for it to complete.
2069  //
2070 
2071  status = IoCallDriver(deviceExtension->PortDeviceObject, irp);
2072 
2073  if (status == STATUS_PENDING) {
2075  }
2076 
2077  //
2078  // Check that request completed without error.
2079  //
2080 
2081  if (SRB_STATUS(Srb->SrbStatus) != SRB_STATUS_SUCCESS) {
2082 
2083  //
2084  // Release the queue if it is frozen.
2085  //
2086 
2087  if (Srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
2089  }
2090 
2091  //
2092  // Update status and determine if request should be retried.
2093  //
2094 
2096  Srb,
2097  IRP_MJ_SCSI,
2098  0,
2099  MAXIMUM_RETRIES - retryCount,
2100  &status);
2101 
2102  if (retry) {
2103 
2106  SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_SELECTION_TIMEOUT) {
2107 
2108  LARGE_INTEGER delay;
2109 
2110  //
2111  // Delay for 2 seconds.
2112  //
2113 
2114  delay.QuadPart = (LONGLONG)( - 10 * 1000 * 1000 * 2 );
2115 
2116  //
2117  // Stall for a while to let the controller spinup.
2118  //
2119 
2121  FALSE,
2122  &delay);
2123 
2124  }
2125 
2126  //
2127  // If retries are not exhausted then retry this operation.
2128  //
2129 
2130  if (retryCount--) {
2131  goto retry;
2132  }
2133  }
2134 
2135  } else {
2136 
2138  }
2139 
2141  return status;
2142 
2143 } // end ScsiClassSendSrbSynchronous()
#define IOCTL_SCSI_EXECUTE_OUT
Definition: cdrw_hw.h:1452
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID _In_ ULONG BufferLength
Definition: cdrom.h:989
PVOID OriginalRequest
Definition: srb.h:258
#define IRP_MJ_FLUSH_BUFFERS
#define TRUE
Definition: types.h:120
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
#define SCSI_ADSENSE_LUN_NOT_READY
Definition: cdrw_hw.h:1218
#define SRB_FLAGS_DATA_IN
Definition: srb.h:392
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define SRB_STATUS(Status)
Definition: srb.h:381
#define SENSE_BUFFER_SIZE
Definition: cdrw_hw.h:1183
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
#define IRP_MJ_SCSI
#define MAXIMUM_RETRIES
Definition: cdrom.h:124
#define FALSE
Definition: types.h:117
VOID NTAPI ScsiClassReleaseQueue(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:939
UCHAR ScsiStatus
Definition: srb.h:244
NTSTATUS NTAPI KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Interval OPTIONAL)
Definition: wait.c:283
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
NTSTATUS NTAPI ClassCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: class2.c:4975
int64_t LONGLONG
Definition: typedefs.h:68
#define STATUS_PENDING
Definition: ntstatus.h:82
PFIXED_SENSE_DATA senseInfoBuffer
Definition: scsi.h:3710
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:389
PIRP NTAPI IoBuildAsynchronousFsdRequest(IN ULONG MajorFunction, IN PDEVICE_OBJECT DeviceObject, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER StartingOffset, IN PIO_STATUS_BLOCK IoStatusBlock)
Definition: irp.c:750
#define IRP_MJ_INTERNAL_DEVICE_CONTROL
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define SRB_FLAGS_NO_DATA_TRANSFER
Definition: srb.h:394
#define SRB_STATUS_QUEUE_FROZEN
Definition: srb.h:378
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define SRB_STATUS_SELECTION_TIMEOUT
Definition: srb.h:342
struct _cl_event * event
Definition: glext.h:7739
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
BOOLEAN NTAPI ScsiClassInterpretSenseInfo(IN PDEVICE_OBJECT DeviceObject, IN PSCSI_REQUEST_BLOCK Srb, IN UCHAR MajorFunctionCode, IN ULONG IoDeviceCode, IN ULONG RetryCount, OUT NTSTATUS *Status)
Definition: class2.c:2148
#define IOCTL_SCSI_EXECUTE_IN
Definition: cdrw_hw.h:1451
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID _In_ ULONG _In_ BOOLEAN WriteToDevice
Definition: cdrom.h:989
#define IOCTL_SCSI_EXECUTE_NONE
Definition: cdrw_hw.h:1453
_In_ UCHAR _Out_opt_ PUCHAR _Out_opt_ PUCHAR AdditionalSenseCode
Definition: scsi.h:3744
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
unsigned char dummy
Definition: maze.c:118
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
unsigned int * PULONG
Definition: retypes.h:1
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:393
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:307
unsigned int ULONG
Definition: retypes.h:1
#define SRB_STATUS_SUCCESS
Definition: srb.h:333
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
IN PSCSI_REQUEST_BLOCK Srb
Definition: class2.h:49
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
static SERVICE_STATUS status
Definition: service.c:31
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ PSCSI_REQUEST_BLOCK _In_opt_ PVOID BufferAddress
Definition: cdrom.h:989
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70
#define PAGED_CODE()
Definition: ps.c:97

Referenced by ScsiClassModeSense(), and ScsiClassReadDriveCapacity().

◆ ScsiClassSplitRequest()

VOID ScsiClassSplitRequest ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN ULONG  MaximumBytes 
)

Definition at line 1298 of file class2.c.

1329 {
1330  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
1333  ULONG transferByteCount = currentIrpStack->Parameters.Read.Length;
1334  LARGE_INTEGER startingOffset = currentIrpStack->Parameters.Read.ByteOffset;
1335  PVOID dataBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
1336  ULONG dataLength = MaximumBytes;
1337  ULONG irpCount = (transferByteCount + MaximumBytes - 1) / MaximumBytes;
1338  ULONG i;
1339  PSCSI_REQUEST_BLOCK srb;
1340 
1341  DebugPrint((2, "ScsiClassSplitRequest: Requires %d IRPs\n", irpCount));
1342  DebugPrint((2, "ScsiClassSplitRequest: Original IRP %lx\n", Irp));
1343 
1344  ASSERT(*(PULONG)deviceExtension != '2slc');
1345 
1346  //
1347  // If all partial transfers complete successfully then the status and
1348  // bytes transferred are already set up. Failing a partial-transfer IRP
1349  // will set status to error and bytes transferred to 0 during
1350  // IoCompletion. Setting bytes transferred to 0 if an IRP fails allows
1351  // asynchronous partial transfers. This is an optimization for the
1352  // successful case.
1353  //
1354 
1355  Irp->IoStatus.Status = STATUS_SUCCESS;
1356  Irp->IoStatus.Information = transferByteCount;
1357 
1358  //
1359  // Save number of IRPs to complete count on current stack
1360  // of original IRP.
1361  //
1362 
1363  nextIrpStack->Parameters.Others.Argument1 = (PVOID)(ULONG_PTR) irpCount;
1364 
1365  for (i = 0; i < irpCount; i++) {
1366 
1367  PIRP newIrp;
1368  PIO_STACK_LOCATION newIrpStack;
1369 
1370  //
1371  // Allocate new IRP.
1372  //
1373 
1374  newIrp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
1375 
1376  if (newIrp == NULL) {
1377 
1378  DebugPrint((1,"ScsiClassSplitRequest: Can't allocate Irp\n"));
1379 
1380  //
1381  // If an Irp can't be allocated then the original request cannot
1382  // be executed. If this is the first request then just fail the
1383  // original request; otherwise just return. When the pending
1384  // requests complete, they will complete the original request.
1385  // In either case set the IRP status to failure.
1386  //
1387 
1388  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
1389  Irp->IoStatus.Information = 0;
1390 
1391  if (i == 0) {
1393  }
1394 
1395  return;
1396  }
1397 
1398  DebugPrint((2, "ScsiClassSplitRequest: New IRP %lx\n", newIrp));
1399 
1400  //
1401  // Write MDL address to new IRP. In the port driver the SRB data
1402  // buffer field is used as an offset into the MDL, so the same MDL
1403  // can be used for each partial transfer. This saves having to build
1404  // a new MDL for each partial transfer.
1405  //
1406 
1407  newIrp->MdlAddress = Irp->MdlAddress;
1408 
1409  //
1410  // At this point there is no current stack. IoSetNextIrpStackLocation
1411  // will make the first stack location the current stack so that the
1412  // SRB address can be written there.
1413  //
1414 
1415  IoSetNextIrpStackLocation(newIrp);
1416  newIrpStack = IoGetCurrentIrpStackLocation(newIrp);
1417 
1418  newIrpStack->MajorFunction = currentIrpStack->MajorFunction;
1419  newIrpStack->Parameters.Read.Length = dataLength;
1420  newIrpStack->Parameters.Read.ByteOffset = startingOffset;
1421  newIrpStack->DeviceObject = DeviceObject;
1422 
1423  //
1424  // Build SRB and CDB.
1425  //
1426 
1428 
1429  //
1430  // Adjust SRB for this partial transfer.
1431  //
1432 
1433  newIrpStack = IoGetNextIrpStackLocation(newIrp);
1434 
1435  srb = newIrpStack->Parameters.Others.Argument1;
1436  srb->DataBuffer = dataBuffer;
1437 
1438  //
1439  // Write original IRP address to new IRP.
1440  //
1441 
1442  newIrp->AssociatedIrp.MasterIrp = Irp;
1443 
1444  //
1445  // Set the completion routine to ScsiClassIoCompleteAssociated.
1446  //
1447 
1448  IoSetCompletionRoutine(newIrp,
1450  srb,
1451  TRUE,
1452  TRUE,
1453  TRUE);
1454 
1455  //
1456  // Call port driver with new request.
1457  //
1458 
1459  IoCallDriver(deviceExtension->PortDeviceObject, newIrp);
1460 
1461  //
1462  // Set up for next request.
1463  //
1464 
1465  dataBuffer = (PCHAR)dataBuffer + MaximumBytes;
1466 
1467  transferByteCount -= MaximumBytes;
1468 
1469  if (transferByteCount > MaximumBytes) {
1470 
1471  dataLength = MaximumBytes;
1472 
1473  } else {
1474 
1475  dataLength = transferByteCount;
1476  }
1477 
1478  //
1479  // Adjust disk byte offset.
1480  //
1481 
1482  startingOffset.QuadPart = startingOffset.QuadPart + MaximumBytes;
1483  }
1484 
1485  return;
1486 
1487 } // end ScsiClassSplitRequest()
NTSTATUS NTAPI ScsiClassIoCompleteAssociated(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: class2.c:1641
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define MmGetMdlVirtualAddress(_Mdl)
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
PVOID DataBuffer
Definition: srb.h:255
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:498
uint32_t ULONG_PTR
Definition: typedefs.h:65
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
ULONG dataLength
Definition: scsi.h:3751
smooth NULL
Definition: ftsmooth.c:416
#define IoCompleteRequest
Definition: irp.c:1240
void * PVOID
Definition: retypes.h:9
#define PCHAR
Definition: match.c:90
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:3202
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetNextIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2691
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2789
_In_ PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2464
unsigned int * PULONG
Definition: retypes.h:1
NTSTATUS NTAPI IoCallDriver(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.c:1218
VOID NTAPI ScsiClassBuildRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp)
Definition: class2.c:2970
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:581
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:3107
return STATUS_SUCCESS
Definition: btrfs.c:3014
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2676
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by CdRomSwitchModeCompletion(), ScsiCdRomStartIo(), and ScsiClassReadWrite().