ReactOS  0.4.14-dev-608-gd495a4f
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 1216 of file class2.c.

1245 {
1247  PSCSI_REQUEST_BLOCK srb;
1248 
1249  srb = &context->Srb;
1250 
1251  //
1252  // If this is an execute srb, then check the return status and make sure.
1253  // the queue is not frozen.
1254  //
1255 
1256  if (srb->Function == SRB_FUNCTION_EXECUTE_SCSI) {
1257 
1258  //
1259  // Check for a frozen queue.
1260  //
1261 
1262  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
1263 
1264  //
1265  // Unfreeze the queue getting the device object from the context.
1266  //
1267 
1268  ScsiClassReleaseQueue(context->DeviceObject);
1269  }
1270  }
1271 
1272  //
1273  // Free the context and the Irp.
1274  //
1275 
1276  if (Irp->MdlAddress != NULL) {
1277  MmUnlockPages(Irp->MdlAddress);
1278  IoFreeMdl(Irp->MdlAddress);
1279 
1280  Irp->MdlAddress = NULL;
1281  }
1282 
1284  IoFreeIrp(Irp);
1285 
1286  //
1287  // Indicate the I/O system should stop processing the Irp completion.
1288  //
1289 
1291 
1292 } // ScsiClassAsynchronousCompletion()
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
Definition: http.c:7098
_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:938
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:1030
#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 2969 of file class2.c.

3003 {
3004  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3007  LARGE_INTEGER startingOffset = currentIrpStack->Parameters.Read.ByteOffset;
3008  PSCSI_REQUEST_BLOCK srb;
3009  PCDB cdb;
3010  ULONG logicalBlockAddress;
3011  USHORT transferBlocks;
3012 
3013  ASSERT(*(PULONG)deviceExtension != '2slc');
3014 
3015  //
3016  // Calculate relative sector address.
3017  //
3018 
3019  logicalBlockAddress = (ULONG)(Int64ShrlMod32(startingOffset.QuadPart, deviceExtension->SectorShift));
3020 
3021  //
3022  // Allocate an Srb.
3023  //
3024 
3025  srb = ExAllocateFromNPagedLookasideList(&deviceExtension->SrbLookasideListHead);
3026 
3027  srb->SrbFlags = 0;
3028 
3029  //
3030  // Write length to SRB.
3031  //
3032 
3034 
3035  //
3036  // Set up IRP Address.
3037  //
3038 
3039  srb->OriginalRequest = Irp;
3040 
3041  //
3042  // Set up target ID and logical unit number.
3043  //
3044 
3045  srb->PathId = deviceExtension->PathId;
3046  srb->TargetId = deviceExtension->TargetId;
3047  srb->Lun = deviceExtension->Lun;
3049  srb->DataBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
3050 
3051  //
3052  // Save byte count of transfer in SRB Extension.
3053  //
3054 
3055  srb->DataTransferLength = currentIrpStack->Parameters.Read.Length;
3056 
3057  //
3058  // Initialize the queue actions field.
3059  //
3060 
3062 
3063  //
3064  // Queue sort key is Relative Block Address.
3065  //
3066 
3067  srb->QueueSortKey = logicalBlockAddress;
3068 
3069  //
3070  // Indicate auto request sense by specifying buffer and size.
3071  //
3072 
3073  srb->SenseInfoBuffer = deviceExtension->SenseData;
3075 
3076  //
3077  // Set timeout value of one unit per 64k bytes of data.
3078  //
3079 
3080  srb->TimeOutValue = ((srb->DataTransferLength + 0xFFFF) >> 16) *
3081  deviceExtension->TimeOutValue;
3082 
3083  //
3084  // Zero statuses.
3085  //
3086 
3087  srb->SrbStatus = srb->ScsiStatus = 0;
3088  srb->NextSrb = 0;
3089 
3090  //
3091  // Indicate that 10-byte CDB's will be used.
3092  //
3093 
3094  srb->CdbLength = 10;
3095 
3096  //
3097  // Fill in CDB fields.
3098  //
3099 
3100  cdb = (PCDB)srb->Cdb;
3101 
3102  //
3103  // Zero 12 bytes for Atapi Packets
3104  //
3105 
3107 
3108  cdb->CDB10.LogicalUnitNumber = deviceExtension->Lun;
3109  transferBlocks = (USHORT)(currentIrpStack->Parameters.Read.Length >> deviceExtension->SectorShift);
3110 
3111  //
3112  // Move little endian values into CDB in big endian format.
3113  //
3114 
3115  cdb->CDB10.LogicalBlockByte0 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte3;
3116  cdb->CDB10.LogicalBlockByte1 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte2;
3117  cdb->CDB10.LogicalBlockByte2 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte1;
3118  cdb->CDB10.LogicalBlockByte3 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte0;
3119 
3120  cdb->CDB10.TransferBlocksMsb = ((PFOUR_BYTE)&transferBlocks)->Byte1;
3121  cdb->CDB10.TransferBlocksLsb = ((PFOUR_BYTE)&transferBlocks)->Byte0;
3122 
3123  //
3124  // Set transfer direction flag and Cdb command.
3125  //
3126 
3127  if (currentIrpStack->MajorFunction == IRP_MJ_READ) {
3128 
3129  DebugPrint((3, "ScsiClassBuildRequest: Read Command\n"));
3130 
3131  srb->SrbFlags |= SRB_FLAGS_DATA_IN;
3132  cdb->CDB10.OperationCode = SCSIOP_READ;
3133 
3134  } else {
3135 
3136  DebugPrint((3, "ScsiClassBuildRequest: Write Command\n"));
3137 
3138  srb->SrbFlags |= SRB_FLAGS_DATA_OUT;
3139  cdb->CDB10.OperationCode = SCSIOP_WRITE;
3140  }
3141 
3142  //
3143  // If this is not a write-through request, then allow caching.
3144  //
3145 
3146  if (!(currentIrpStack->Flags & SL_WRITE_THROUGH)) {
3147 
3149 
3150  } else {
3151 
3152  //
3153  // If write caching is enable then force media access in the
3154  // cdb.
3155  //
3156 
3157  if (deviceExtension->DeviceFlags & DEV_WRITE_CACHE) {
3158  cdb->CDB10.ForceUnitAccess = TRUE;
3159  }
3160  }
3161 
3162  //
3163  // Or in the default flags from the device object.
3164  //
3165 
3166  srb->SrbFlags |= deviceExtension->SrbFlags;
3167 
3168  //
3169  // Set up major SCSI function.
3170  //
3171 
3172  nextIrpStack->MajorFunction = IRP_MJ_SCSI;
3173 
3174  //
3175  // Save SRB address in next stack for port driver.
3176  //
3177 
3178  nextIrpStack->Parameters.Scsi.Srb = srb;
3179 
3180  //
3181  // Save retry count in current IRP stack.
3182  //
3183 
3184  currentIrpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
3185 
3186  //
3187  // Set up IoCompletion routine address.
3188  //
3189 
3191 
3192  return;
3193 
3194 } // end ScsiClassBuildRequest()
struct _FOUR_BYTE * PFOUR_BYTE
#define TRUE
Definition: types.h:120
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
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:515
#define IRP_MJ_SCSI
UCHAR ScsiStatus
Definition: srb.h:244
#define SCSIOP_READ
Definition: cdrw_hw.h:905
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#define SCSIOP_WRITE
Definition: cdrw_hw.h:906
union _CDB * PCDB
void * PVOID
Definition: retypes.h:9
UCHAR TargetId
Definition: srb.h:246
#define MAXIMUM_RETRIES
Definition: class2.h:14
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:1491
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:2647
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
#define Int64ShrlMod32(a, b)
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
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
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:1781
#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:261
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
ULONG QueueSortKey
Definition: srb.h:262
LONGLONG QuadPart
Definition: typedefs.h:112

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 4488 of file class2.c.

4519 {
4520  IO_STATUS_BLOCK ioStatus;
4521  PIRP irp;
4522  PIO_STACK_LOCATION irpStack;
4523  KEVENT event;
4524  NTSTATUS status;
4525  SCSI_REQUEST_BLOCK srb;
4526 
4527  PAGED_CODE();
4528 
4529  if (NewPortDeviceObject != NULL) {
4530  *NewPortDeviceObject = NULL;
4531  }
4532 
4533  //
4534  // Clear the SRB fields.
4535  //
4536 
4537  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
4538 
4539  //
4540  // Write length to SRB.
4541  //
4542 
4544 
4545  //
4546  // Set SCSI bus address.
4547  //
4548 
4549  srb.PathId = LunInfo->PathId;
4550  srb.TargetId = LunInfo->TargetId;
4551  srb.Lun = LunInfo->Lun;
4552 
4555 
4556  //
4557  // Set the event object to the unsignaled state.
4558  // It will be used to signal request completion.
4559  //
4560 
4562 
4563  //
4564  // Build synchronous request with no transfer.
4565  //
4566 
4568  PortDeviceObject,
4569  NULL,
4570  0,
4571  NULL,
4572  0,
4573  TRUE,
4574  &event,
4575  &ioStatus);
4576 
4577  if (irp == NULL) {
4578 
4579  DebugPrint((1, "ScsiClassClaimDevice: Can't allocate Irp\n"));
4581  }
4582 
4583  irpStack = IoGetNextIrpStackLocation(irp);
4584 
4585  //
4586  // Save SRB address in next stack for port driver.
4587  //
4588 
4589  irpStack->Parameters.Scsi.Srb = &srb;
4590 
4591  //
4592  // Set up IRP Address.
4593  //
4594 
4595  srb.OriginalRequest = irp;
4596 
4597  //
4598  // Call the port driver with the request and wait for it to complete.
4599  //
4600 
4601  status = IoCallDriver(PortDeviceObject, irp);
4602  if (status == STATUS_PENDING) {
4603 
4605  status = ioStatus.Status;
4606  }
4607 
4608  //
4609  // If this is a release request, then just decrement the reference count
4610  // and return. The status does not matter.
4611  //
4612 
4613  if (Release) {
4614 
4615  //ObDereferenceObject(PortDeviceObject);
4616  return STATUS_SUCCESS;
4617  }
4618 
4619  if (!NT_SUCCESS(status)) {
4620  return status;
4621  }
4622 
4623  ASSERT(srb.DataBuffer != NULL);
4624 
4625  //
4626  // Reference the new port driver object so that it will not go away while
4627  // it is being used.
4628  //
4629 
4631  0,
4632  NULL,
4633  KernelMode );
4634 
4635  if (!NT_SUCCESS(status)) {
4636 
4637  return status;
4638  }
4640 
4641  //
4642  // Return the new port device object pointer.
4643  //
4644 
4645  if (NewPortDeviceObject != NULL) {
4646  *NewPortDeviceObject = srb.DataBuffer;
4647  }
4648 
4649  return status;
4650 }
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PVOID OriginalRequest
Definition: srb.h:258
_In_ BOOLEAN Release
Definition: classpnp.h:929
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 PAGED_CODE()
Definition: video.h:57
#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:2647
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:261
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ ScsiClassDeviceControl()

NTSTATUS ScsiClassDeviceControl ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 3602 of file class2.c.

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

4684 {
4686  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
4687  PSCSI_REQUEST_BLOCK srb;
4688 
4689  ASSERT(*(PULONG)deviceExtension != '2slc');
4690 
4691  //
4692  // Get a pointer to the SRB.
4693  //
4694 
4695  srb = irpStack->Parameters.Scsi.Srb;
4696 
4697  //
4698  // Set SCSI bus address.
4699  //
4700 
4701  srb->PathId = deviceExtension->PathId;
4702  srb->TargetId = deviceExtension->TargetId;
4703  srb->Lun = deviceExtension->Lun;
4704 
4705  //
4706  // NOTICE: The SCSI-II specification indicates that this field should be
4707  // zero; however, some target controllers ignore the logical unit number
4708  // in the IDENTIFY message and only look at the logical unit number field
4709  // in the CDB.
4710  //
4711 
4712  srb->Cdb[1] |= deviceExtension->Lun << 5;
4713 
4714  //
4715  // Set the parameters in the next stack location.
4716  //
4717 
4718  irpStack = IoGetNextIrpStackLocation(Irp);
4719 
4720  irpStack->Parameters.Scsi.Srb = srb;
4721  irpStack->MajorFunction = IRP_MJ_SCSI;
4722  irpStack->MinorFunction = IRP_MN_SCSI_CLASS;
4723 
4725  return IoCallDriver(deviceExtension->PortDeviceObject, Irp);
4726 }
#define TRUE
Definition: types.h:120
UCHAR Cdb[16]
Definition: srb.h:271
_In_ PIRP Irp
Definition: csq.h:116
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
#define IRP_MJ_SCSI
NTSTATUS NTAPI ClassIoCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: class2.c:4730
PVOID DeviceExtension
Definition: env_spec_w32.h:418
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:2647
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
UCHAR PathId
Definition: srb.h:245
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:2772

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 2147 of file class2.c.

2183 {
2184  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
2185  PDEVICE_EXTENSION physicalExtension = deviceExtension->PhysicalDevice->DeviceExtension;
2186  PSENSE_DATA senseBuffer = Srb->SenseInfoBuffer;
2187  BOOLEAN retry = TRUE;
2188  BOOLEAN logError = FALSE;
2189  ULONG badSector = 0;
2190  ULONG uniqueId = 0;
2191  NTSTATUS logStatus;
2192  ULONG readSector;
2193  ULONG index;
2194  PIO_ERROR_LOG_PACKET errorLogEntry;
2195 #if DBG
2196  ULONG i;
2197 #endif
2198 
2199  ASSERT(*(PULONG)deviceExtension != '2slc');
2200 
2201  //
2202  // Check that request sense buffer is valid.
2203  //
2204 
2205 #if DBG
2206  DebugPrint((3, "Opcode %x\nParameters: ",Srb->Cdb[0]));
2207  for (i = 1; i < 12; i++) {
2208  DebugPrint((3,"%x ",Srb->Cdb[i]));
2209  }
2210  DebugPrint((3,"\n"));
2211 #endif
2212 
2213  if (Srb->SrbStatus & SRB_STATUS_AUTOSENSE_VALID &&
2214  Srb->SenseInfoBufferLength >= FIELD_OFFSET(SENSE_DATA, CommandSpecificInformation)) {
2215 
2216  DebugPrint((1,"ScsiClassInterpretSenseInfo: Error code is %x\n",
2217  senseBuffer->ErrorCode));
2218  DebugPrint((1,"ScsiClassInterpretSenseInfo: Sense key is %x\n",
2219  senseBuffer->SenseKey));
2220  DebugPrint((1, "ScsiClassInterpretSenseInfo: Additional sense code is %x\n",
2221  senseBuffer->AdditionalSenseCode));
2222  DebugPrint((1, "ScsiClassInterpretSenseInfo: Additional sense code qualifier is %x\n",
2223  senseBuffer->AdditionalSenseCodeQualifier));
2224 
2225  //
2226  // Zero the additional sense code and additional sense code qualifier
2227  // if they were not returned by the device.
2228  //
2229 
2230  readSector = senseBuffer->AdditionalSenseLength +
2231  FIELD_OFFSET(SENSE_DATA, AdditionalSenseLength);
2232 
2233  if (readSector > Srb->SenseInfoBufferLength) {
2234  readSector = Srb->SenseInfoBufferLength;
2235  }
2236 
2237  if (readSector <= FIELD_OFFSET(SENSE_DATA, AdditionalSenseCode)) {
2238  senseBuffer->AdditionalSenseCode = 0;
2239  }
2240 
2241  if (readSector <= FIELD_OFFSET(SENSE_DATA, AdditionalSenseCodeQualifier)) {
2242  senseBuffer->AdditionalSenseCodeQualifier = 0;
2243  }
2244 
2245  switch (senseBuffer->SenseKey & 0xf) {
2246 
2247  case SCSI_SENSE_NOT_READY:
2248 
2249  DebugPrint((1,"ScsiClassInterpretSenseInfo: Device not ready\n"));
2251 
2252  switch (senseBuffer->AdditionalSenseCode) {
2253 
2255 
2256  DebugPrint((1,"ScsiClassInterpretSenseInfo: Lun not ready\n"));
2257 
2258  switch (senseBuffer->AdditionalSenseCodeQualifier) {
2259 
2261 
2262  DebugPrint((1, "ScsiClassInterpretSenseInfo:"
2263  " In process of becoming ready\n"));
2264  break;
2265 
2267 
2268  DebugPrint((1, "ScsiClassInterpretSenseInfo:"
2269  " Manual intervention required\n"));
2271  retry = FALSE;
2272  break;
2273 
2275 
2276  DebugPrint((1, "ScsiClassInterpretSenseInfo: Format in progress\n"));
2277  retry = FALSE;
2278  break;
2279 
2281 
2282  default:
2283 
2284  DebugPrint((1, "ScsiClassInterpretSenseInfo:"
2285  " Initializing command required\n"));
2286 
2287  //
2288  // This sense code/additional sense code
2289  // combination may indicate that the device
2290  // needs to be started. Send an start unit if this
2291  // is a disk device.
2292  //
2293 
2294  if (deviceExtension->DeviceFlags & DEV_SAFE_START_UNIT) {
2296  }
2297 
2298  break;
2299 
2300  } // end switch (senseBuffer->AdditionalSenseCodeQualifier)
2301 
2302  break;
2303 
2305 
2306  DebugPrint((1,
2307  "ScsiClassInterpretSenseInfo:"
2308  " No Media in device.\n"));
2310  retry = FALSE;
2311 
2312  //
2313  // signal autorun that there isn't any media in the device
2314  //
2315 
2316  if((deviceExtension->MediaChangeEvent != NULL)&&
2317  (!deviceExtension->MediaChangeNoMedia)) {
2318  KeSetEvent(deviceExtension->MediaChangeEvent,
2319  (KPRIORITY) 0,
2320  FALSE);
2321  DebugPrint((0, "ScsiClassInterpretSenseInfo:"
2322  "Detected No Media In Device "
2323  "[irp = 0x%lx]\n", Srb->OriginalRequest));
2324  deviceExtension->MediaChangeNoMedia = TRUE;
2325  }
2326 
2327  break;
2328  } // end switch (senseBuffer->AdditionalSenseCode)
2329 
2330  break;
2331 
2333 
2334  DebugPrint((1, "ScsiClassInterpretSenseInfo: Media write protected\n"));
2336  retry = FALSE;
2337  break;
2338 
2340 
2341  DebugPrint((1,"ScsiClassInterpretSenseInfo: Bad media\n"));
2343 
2344  retry = FALSE;
2345  logError = TRUE;
2346  uniqueId = 256;
2347  logStatus = 0;//IO_ERR_BAD_BLOCK;
2348  break;
2349 
2351 
2352  DebugPrint((1,"ScsiClassInterpretSenseInfo: Hardware error\n"));
2354 
2355  logError = TRUE;
2356  uniqueId = 257;
2357  logStatus = 0;//IO_ERR_CONTROLLER_ERROR;
2358 
2359  break;
2360 
2362 
2363  DebugPrint((1, "ScsiClassInterpretSenseInfo: Illegal SCSI request\n"));
2365 
2366  switch (senseBuffer->AdditionalSenseCode) {
2367 
2369  DebugPrint((1, "ScsiClassInterpretSenseInfo: Illegal command\n"));
2370  retry = FALSE;
2371  break;
2372 
2374  DebugPrint((1, "ScsiClassInterpretSenseInfo: Illegal block address\n"));
2376  retry = FALSE;
2377  break;
2378 
2380  DebugPrint((1,"ScsiClassInterpretSenseInfo: Invalid LUN\n"));
2382  retry = FALSE;
2383  break;
2384 
2386  DebugPrint((1,"ScsiClassInterpretSenseInfo: Music area\n"));
2387  retry = FALSE;
2388  break;
2389 
2391  DebugPrint((1,"ScsiClassInterpretSenseInfo: Data area\n"));
2392  retry = FALSE;
2393  break;
2394 
2396  DebugPrint((1, "ScsiClassInterpretSenseInfo: Volume overflow\n"));
2397  retry = FALSE;
2398  break;
2399 
2401  DebugPrint((1, "ScsiClassInterpretSenseInfo: Invalid CDB\n"));
2402 
2403  //
2404  // Check if write cache enabled.
2405  //
2406 
2407  if (deviceExtension->DeviceFlags & DEV_WRITE_CACHE) {
2408 
2409  //
2410  // Assume FUA is not supported.
2411  //
2412 
2413  deviceExtension->DeviceFlags &= ~DEV_WRITE_CACHE;
2414  retry = TRUE;
2415 
2416  } else {
2417  retry = FALSE;
2418  }
2419 
2420  break;
2421 
2422  } // end switch (senseBuffer->AdditionalSenseCode)
2423 
2424  break;
2425 
2427 
2428  switch (senseBuffer->AdditionalSenseCode) {
2430  DebugPrint((1, "ScsiClassInterpretSenseInfo: Media changed\n"));
2431 
2432  if(deviceExtension->MediaChangeEvent != NULL) {
2433 
2434  KeSetEvent(deviceExtension->MediaChangeEvent,
2435  (KPRIORITY) 0,
2436  FALSE);
2437  DebugPrint((0, "ScsiClassInterpretSenseInfo:"
2438  "New Media Found - Setting MediaChanged event"
2439  " [irp = 0x%lx]\n", Srb->OriginalRequest));
2440  deviceExtension->MediaChangeNoMedia = FALSE;
2441 
2442  }
2443  break;
2444 
2446  DebugPrint((1,"ScsiClassInterpretSenseInfo: Bus reset\n"));
2447  break;
2448 
2449  default:
2450  DebugPrint((1,"ScsiClassInterpretSenseInfo: Unit attention\n"));
2451  break;
2452 
2453  } // end switch (senseBuffer->AdditionalSenseCode)
2454 
2455  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA &&
2456  DeviceObject->Vpb->Flags & VPB_MOUNTED) {
2457 
2458  //
2459  // Set bit to indicate that media may have changed
2460  // and volume needs verification.
2461  //
2462 
2464 
2466  retry = FALSE;
2467 
2468  } else {
2469 
2471 
2472  }
2473 
2474  //
2475  // A media change may have occured so increment the change
2476  // count for the physical device
2477  //
2478 
2479  physicalExtension->MediaChangeCount++;
2480 
2481  DebugPrint((2, "ScsiClassInterpretSenseInfo - Media change "
2482  "count for device %d is %d\n",
2483  physicalExtension->DeviceNumber,
2484  physicalExtension->MediaChangeCount));
2485 
2486  break;
2487 
2489 
2490  DebugPrint((1,"ScsiClassInterpretSenseInfo: Command aborted\n"));
2492  break;
2493 
2495 
2496  DebugPrint((1,"ScsiClassInterpretSenseInfo: Recovered error\n"));
2498  retry = FALSE;
2499  logError = TRUE;
2500  uniqueId = 258;
2501 
2502  switch(senseBuffer->AdditionalSenseCode) {
2505  logStatus = 0;//IO_ERR_SEEK_ERROR;
2506  break;
2507 
2510  logStatus = 0;//IO_RECOVERED_VIA_ECC;
2511  break;
2512 
2513  default:
2514  logStatus = 0;//IO_ERR_CONTROLLER_ERROR;
2515  break;
2516 
2517  } // end switch(senseBuffer->AdditionalSenseCode)
2518 
2519  if (senseBuffer->IncorrectLength) {
2520 
2521  DebugPrint((1, "ScsiClassInterpretSenseInfo: Incorrect length detected.\n"));
2523  }
2524 
2525  break;
2526 
2527  case SCSI_SENSE_NO_SENSE:
2528 
2529  //
2530  // Check other indicators.
2531  //
2532 
2533  if (senseBuffer->IncorrectLength) {
2534 
2535  DebugPrint((1, "ScsiClassInterpretSenseInfo: Incorrect length detected.\n"));
2537  retry = FALSE;
2538 
2539  } else {
2540 
2541  DebugPrint((1, "ScsiClassInterpretSenseInfo: No specific sense key\n"));
2543  retry = TRUE;
2544  }
2545 
2546  break;
2547 
2548  default:
2549 
2550  DebugPrint((1, "ScsiClassInterpretSenseInfo: Unrecognized sense code\n"));
2552  break;
2553 
2554  } // end switch (senseBuffer->SenseKey & 0xf)
2555 
2556  //
2557  // Try to determine the bad sector from the inquiry data.
2558  //
2559 
2560  if ((((PCDB)Srb->Cdb)->CDB10.OperationCode == SCSIOP_READ ||
2561  ((PCDB)Srb->Cdb)->CDB10.OperationCode == SCSIOP_VERIFY ||
2562  ((PCDB)Srb->Cdb)->CDB10.OperationCode == SCSIOP_WRITE)) {
2563 
2564  for (index = 0; index < 4; index++) {
2565  badSector = (badSector << 8) | senseBuffer->Information[index];
2566  }
2567 
2568  readSector = 0;
2569  for (index = 0; index < 4; index++) {
2570  readSector = (readSector << 8) | Srb->Cdb[index+2];
2571  }
2572 
2573  index = (((PCDB)Srb->Cdb)->CDB10.TransferBlocksMsb << 8) |
2574  ((PCDB)Srb->Cdb)->CDB10.TransferBlocksLsb;
2575 
2576  //
2577  // Make sure the bad sector is within the read sectors.
2578  //
2579 
2580  if (!(badSector >= readSector && badSector < readSector + index)) {
2581  badSector = readSector;
2582  }
2583  }
2584 
2585  } else {
2586 
2587  //
2588  // Request sense buffer not valid. No sense information
2589  // to pinpoint the error. Return general request fail.
2590  //
2591 
2592  DebugPrint((1,"ScsiClassInterpretSenseInfo: Request sense info not valid. SrbStatus %2x\n",
2593  SRB_STATUS(Srb->SrbStatus)));
2594  retry = TRUE;
2595 
2596  switch (SRB_STATUS(Srb->SrbStatus)) {
2599  case SRB_STATUS_NO_DEVICE:
2600  case SRB_STATUS_NO_HBA:
2603  retry = FALSE;
2604  break;
2605 
2607  case SRB_STATUS_ABORTED:
2608  case SRB_STATUS_TIMEOUT:
2609 
2610  //
2611  // Update the error count for the device.
2612  //
2613 
2614  deviceExtension->ErrorCount++;
2616  break;
2617 
2619  logError = TRUE;
2620  logStatus = 0;//IO_ERR_NOT_READY;
2621  uniqueId = 260;
2623  retry = FALSE;
2624  break;
2625 
2628  retry = FALSE;
2629  break;
2630 
2632 
2633  //
2634  // Update the error count for the device.
2635  //
2636 
2637  deviceExtension->ErrorCount++;
2639 
2640  //
2641  // If there was phase sequence error then limit the number of
2642  // retries.
2643  //
2644 
2645  if (RetryCount > 1 ) {
2646  retry = FALSE;
2647  }
2648 
2649  break;
2650 
2652 
2653  //
2654  // If the status needs verification bit is set. Then set
2655  // the status to need verification and no retry; otherwise,
2656  // just retry the request.
2657  //
2658 
2660 
2662  retry = FALSE;
2663  } else {
2665  }
2666 
2667  break;
2668 
2670 
2671  //
2672  // An invalid request was attempted.
2673  //
2674 
2676  retry = FALSE;
2677  break;
2678 
2681 
2682  //
2683  // Update the error count for the device.
2684  //
2685 
2686  deviceExtension->ErrorCount++;
2687 
2688  //
2689  // Fall through to below.
2690  //
2691 
2692  case SRB_STATUS_BUS_RESET:
2694  break;
2695 
2696  case SRB_STATUS_ERROR:
2697 
2699  if (Srb->ScsiStatus == 0) {
2700 
2701  //
2702  // This is some strange return code. Update the error
2703  // count for the device.
2704  //
2705 
2706  deviceExtension->ErrorCount++;
2707 
2708  } if (Srb->ScsiStatus == SCSISTAT_BUSY) {
2709 
2711 
2712  } if (Srb->ScsiStatus == SCSISTAT_RESERVATION_CONFLICT) {
2713 
2715  retry = FALSE;
2716 
2717  }
2718 
2719  break;
2720 
2721  default:
2722  logError = TRUE;
2723  logStatus = 0;//IO_ERR_CONTROLLER_ERROR;
2724  uniqueId = 259;
2726  break;
2727 
2728  }
2729 
2730  //
2731  // If the error count has exceeded the error limit, then disable
2732  // any tagged queuing, multiple requests per lu queueing
2733  // and synchronous data transfers.
2734  //
2735 
2736  if (deviceExtension->ErrorCount == 4) {
2737 
2738  //
2739  // Clearing the no queue freeze flag prevents the port driver
2740  // from sending multiple requests per logical unit.
2741  //
2742 
2743  deviceExtension->SrbFlags &= ~(SRB_FLAGS_QUEUE_ACTION_ENABLE |
2745 
2746  deviceExtension->SrbFlags |= SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
2747  DebugPrint((1, "ScsiClassInterpretSenseInfo: Too many errors disabling tagged queuing and synchronous data tranfers.\n"));
2748 
2749  } else if (deviceExtension->ErrorCount == 8) {
2750 
2751  //
2752  // If a second threshold is reached, disable disconnects.
2753  //
2754 
2755  deviceExtension->SrbFlags |= SRB_FLAGS_DISABLE_DISCONNECT;
2756  DebugPrint((1, "ScsiClassInterpretSenseInfo: Too many errors disabling disconnects.\n"));
2757  }
2758  }
2759 
2760  //
2761  // If there is a class specific error handler call it.
2762  //
2763 
2764  if (deviceExtension->ClassError != NULL) {
2765 
2766  deviceExtension->ClassError(DeviceObject,
2767  Srb,
2768  Status,
2769  &retry);
2770  }
2771 
2772  //
2773  // Log an error if necessary.
2774  //
2775 
2776  if (logError) {
2777 
2779  DeviceObject,
2780  sizeof(IO_ERROR_LOG_PACKET) + 5 * sizeof(ULONG));
2781 
2782  if (errorLogEntry == NULL) {
2783 
2784  //
2785  // Return if no packet could be allocated.
2786  //
2787 
2788  return retry;
2789 
2790  }
2791 
2792  if (retry && RetryCount < MAXIMUM_RETRIES) {
2793  errorLogEntry->FinalStatus = STATUS_SUCCESS;
2794  } else {
2795  errorLogEntry->FinalStatus = *Status;
2796  }
2797 
2798  //
2799  // Calculate the device offset if there is a geometry.
2800  //
2801 
2802  if (deviceExtension->DiskGeometry != NULL) {
2803 
2804  errorLogEntry->DeviceOffset.QuadPart = (LONGLONG) badSector;
2805  errorLogEntry->DeviceOffset = RtlExtendedIntegerMultiply(
2806  errorLogEntry->DeviceOffset,
2807  deviceExtension->DiskGeometry->Geometry.BytesPerSector);
2808  }
2809 
2810  errorLogEntry->ErrorCode = logStatus;
2811  errorLogEntry->SequenceNumber = 0;
2812  errorLogEntry->MajorFunctionCode = MajorFunctionCode;
2813  errorLogEntry->IoControlCode = IoDeviceCode;
2814  errorLogEntry->RetryCount = (UCHAR) RetryCount;
2815  errorLogEntry->UniqueErrorValue = uniqueId;
2816  errorLogEntry->DumpDataSize = 6 * sizeof(ULONG);
2817  errorLogEntry->DumpData[0] = Srb->PathId;
2818  errorLogEntry->DumpData[1] = Srb->TargetId;
2819  errorLogEntry->DumpData[2] = Srb->Lun;
2820  errorLogEntry->DumpData[3] = 0;
2821  errorLogEntry->DumpData[4] = Srb->SrbStatus << 8 | Srb->ScsiStatus;
2822 
2823  if (senseBuffer != NULL) {
2824  errorLogEntry->DumpData[5] = senseBuffer->SenseKey << 16 |
2825  senseBuffer->AdditionalSenseCode << 8 |
2826  senseBuffer->AdditionalSenseCodeQualifier;
2827 
2828  }
2829 
2830  //
2831  // Write the error log packet.
2832  //
2833 
2834  IoWriteErrorLogEntry(errorLogEntry);
2835  }
2836 
2837  return retry;
2838 
2839 } // 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 TRUE
Definition: types.h:120
#define STATUS_DATA_OVERRUN
Definition: udferr_usr.h:152
#define SRB_STATUS_AUTOSENSE_VALID
Definition: srb.h:379
NTSTATUS FinalStatus
Definition: iotypes.h:1966
#define SRB_FLAGS_NO_QUEUE_FREEZE
Definition: srb.h:396
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:620
LONG KPRIORITY
Definition: compat.h:462
LARGE_INTEGER DeviceOffset
Definition: iotypes.h:1969
#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
NTSTATUS ErrorCode
Definition: iotypes.h:1964
#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 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
PVOID DeviceExtension
Definition: env_spec_w32.h:418
#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
NTSYSAPI LONGLONG WINAPI RtlExtendedIntegerMultiply(LONGLONG, INT)
UCHAR Information[4]
Definition: cdrw_hw.h:1172
#define MAXIMUM_RETRIES
Definition: class2.h:14
#define STATUS_DEVICE_NOT_CONNECTED
Definition: udferr_usr.h:160
PVOID NTAPI IoAllocateErrorLogEntry(IN PVOID IoObject, IN UCHAR EntrySize)
Definition: error.c:520
UCHAR AdditionalSenseCodeQualifier
Definition: cdrw_hw.h:1176
int64_t LONGLONG
Definition: typedefs.h:66
#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:465
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:349
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
#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
Status
Definition: gdiplustypes.h:24
#define SCSI_SENSEQ_INIT_COMMAND_REQUIRED
Definition: cdrw_hw.h:1314
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
VOID NTAPI StartUnit(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:1081
#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:254
unsigned int * PULONG
Definition: retypes.h:1
UCHAR IncorrectLength
Definition: cdrw_hw.h:1169
#define STATUS_IO_TIMEOUT
Definition: udferr_usr.h:163
#define DEV_SAFE_START_UNIT
Definition: class2.h:35
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:2938
#define VPB_MOUNTED
Definition: iotypes.h:1764
#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:465
LONGLONG QuadPart
Definition: typedefs.h:112
#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 1491 of file class2.c.

1522 {
1525  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
1526  NTSTATUS status;
1527  BOOLEAN retry;
1528 
1529  ASSERT(*(PULONG)deviceExtension != '2slc');
1530 
1531  //
1532  // Check SRB status for success of completing request.
1533  //
1534 
1535  if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
1536 
1537  DebugPrint((2,"ScsiClassIoComplete: IRP %lx, SRB %lx\n", Irp, srb));
1538 
1539  //
1540  // Release the queue if it is frozen.
1541  //
1542 
1543  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
1545  }
1546 
1548  DeviceObject,
1549  srb,
1550  irpStack->MajorFunction,
1551  irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL ? irpStack->Parameters.DeviceIoControl.IoControlCode : 0,
1552  MAXIMUM_RETRIES - PtrToUlong(irpStack->Parameters.Others.Argument4),
1553  &status);
1554 
1555  //
1556  // If the status is verified required and the this request
1557  // should bypass verify required then retry the request.
1558  //
1559 
1560  if (irpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME &&
1562 
1564  retry = TRUE;
1565  }
1566 
1567  if (retry && (irpStack->Parameters.Others.Argument4 = (PVOID)((ULONG_PTR)irpStack->Parameters.Others.Argument4-1))) {
1568 
1569  //
1570  // Retry request.
1571  //
1572 
1573  DebugPrint((1, "Retry request %lx\n", Irp));
1576  }
1577  } else {
1578 
1579  //
1580  // Set status for successful request.
1581  //
1582 
1584 
1585  } // end if (SRB_STATUS(srb->SrbStatus) ...
1586 
1587  //
1588  // Return SRB to list.
1589  //
1590 
1591  ExFreeToNPagedLookasideList(&deviceExtension->SrbLookasideListHead,
1592  srb);
1593 
1594  //
1595  // Set status in completing IRP.
1596  //
1597 
1598  Irp->IoStatus.Status = status;
1599  if ((NT_SUCCESS(status)) && (Irp->Flags & IRP_PAGING_IO)) {
1600  ASSERT(Irp->IoStatus.Information);
1601  }
1602 
1603  //
1604  // Set the hard error if necessary.
1605  //
1606 
1608 
1609  //
1610  // Store DeviceObject for filesystem, and clear
1611  // in IoStatus.Information field.
1612  //
1613 
1615  Irp->IoStatus.Information = 0;
1616  }
1617 
1618  //
1619  // If pending has be returned for this irp then mark the current stack as
1620  // pending.
1621  //
1622 
1623  if (Irp->PendingReturned) {
1625  }
1626 
1627  if (deviceExtension->ClassStartIo) {
1628  if (irpStack->MajorFunction != IRP_MJ_DEVICE_CONTROL) {
1630  }
1631  }
1632 
1633  return status;
1634 
1635 } // end ScsiClassIoComplete()
#define TRUE
Definition: types.h:120
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2769
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI RetryRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp, PSCSI_REQUEST_BLOCK Srb, BOOLEAN Associated)
Definition: class2.c:2844
#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:63
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
VOID NTAPI ScsiClassReleaseQueue(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:938
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1780
#define MAXIMUM_RETRIES
Definition: class2.h:14
#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:2147
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
unsigned int * PULONG
Definition: retypes.h:1
#define IRP_PAGING_IO
struct tagContext Context
Definition: acpixf.h:1030
#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:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
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 1640 of file class2.c.

1674 {
1677  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
1678  PIRP originalIrp = Irp->AssociatedIrp.MasterIrp;
1679  LONG irpCount;
1680  NTSTATUS status;
1681  BOOLEAN retry;
1682 
1683  ASSERT(*(PULONG)deviceExtension != '2slc');
1684 
1685  //
1686  // Check SRB status for success of completing request.
1687  //
1688 
1689  if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
1690 
1691  DebugPrint((2,"ScsiClassIoCompleteAssociated: IRP %lx, SRB %lx", Irp, srb));
1692 
1693  //
1694  // Release the queue if it is frozen.
1695  //
1696 
1697  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
1699  }
1700 
1702  DeviceObject,
1703  srb,
1704  irpStack->MajorFunction,
1705  irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL ? irpStack->Parameters.DeviceIoControl.IoControlCode : 0,
1706  MAXIMUM_RETRIES - PtrToUlong(irpStack->Parameters.Others.Argument4),
1707  &status);
1708 
1709  //
1710  // If the status is verified required and the this request
1711  // should bypass verify required then retry the request.
1712  //
1713 
1714  if (irpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME &&
1716 
1718  retry = TRUE;
1719  }
1720 
1721  if (retry && (irpStack->Parameters.Others.Argument4 = (PVOID)((ULONG_PTR)irpStack->Parameters.Others.Argument4-1))) {
1722 
1723  //
1724  // Retry request. If the class driver has supplied a StartIo,
1725  // call it directly for retries.
1726  //
1727 
1728  DebugPrint((1, "Retry request %lx\n", Irp));
1729 
1730  /*
1731  if (!deviceExtension->ClassStartIo) {
1732  RetryRequest(DeviceObject, Irp, srb, TRUE);
1733  } else {
1734  deviceExtension->ClassStartIo(DeviceObject, Irp);
1735  }
1736  */
1737 
1739 
1741  }
1742 
1743 
1744 
1745  } else {
1746 
1747  //
1748  // Set status for successful request.
1749  //
1750 
1752 
1753  } // end if (SRB_STATUS(srb->SrbStatus) ...
1754 
1755  //
1756  // Return SRB to list.
1757  //
1758 
1759  ExFreeToNPagedLookasideList(&deviceExtension->SrbLookasideListHead,
1760  srb);
1761 
1762  //
1763  // Set status in completing IRP.
1764  //
1765 
1766  Irp->IoStatus.Status = status;
1767 
1768  DebugPrint((2, "ScsiClassIoCompleteAssociated: Partial xfer IRP %lx\n", Irp));
1769 
1770  //
1771  // Get next stack location. This original request is unused
1772  // except to keep track of the completing partial IRPs so the
1773  // stack location is valid.
1774  //
1775 
1776  irpStack = IoGetNextIrpStackLocation(originalIrp);
1777 
1778  //
1779  // Update status only if error so that if any partial transfer
1780  // completes with error, then the original IRP will return with
1781  // error. If any of the asynchronous partial transfer IRPs fail,
1782  // with an error then the original IRP will return 0 bytes transfered.
1783  // This is an optimization for successful transfers.
1784  //
1785 
1786  if (!NT_SUCCESS(status)) {
1787 
1788  originalIrp->IoStatus.Status = status;
1789  originalIrp->IoStatus.Information = 0;
1790 
1791  //
1792  // Set the hard error if necessary.
1793  //
1794 
1796 
1797  //
1798  // Store DeviceObject for filesystem.
1799  //
1800 
1802  }
1803  }
1804 
1805  //
1806  // Decrement and get the count of remaining IRPs.
1807  //
1808 
1809  irpCount = InterlockedDecrement((PLONG)&irpStack->Parameters.Others.Argument1);
1810 
1811  DebugPrint((2, "ScsiClassIoCompleteAssociated: Partial IRPs left %d\n",
1812  irpCount));
1813 
1814  //
1815  // Old bug could cause irp count to negative
1816  //
1817 
1818  ASSERT(irpCount >= 0);
1819 
1820  if (irpCount == 0) {
1821 
1822  //
1823  // All partial IRPs have completed.
1824  //
1825 
1826  DebugPrint((2,
1827  "ScsiClassIoCompleteAssociated: All partial IRPs complete %lx\n",
1828  originalIrp));
1829 
1830  IoCompleteRequest(originalIrp, IO_DISK_INCREMENT);
1831 
1832  //
1833  // If the class driver has supplied a startio, start the
1834  // next request.
1835  //
1836 
1837  if (deviceExtension->ClassStartIo) {
1839  }
1840  }
1841 
1842  //
1843  // Deallocate IRP and indicate the I/O system should not attempt any more
1844  // processing.
1845  //
1846 
1847  IoFreeIrp(Irp);
1849 
1850 } // end ScsiClassIoCompleteAssociated()
#define TRUE
Definition: types.h:120
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:68
_In_ PIRP Irp
Definition: csq.h:116
#define IoIsErrorUserInduced(Status)
Definition: iofuncs.h:2769
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI RetryRequest(PDEVICE_OBJECT DeviceObject, PIRP Irp, PSCSI_REQUEST_BLOCK Srb, BOOLEAN Associated)
Definition: class2.c:2844
#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:63
#define STATUS_IO_DEVICE_ERROR
Definition: udferr_usr.h:179
#define IO_DISK_INCREMENT
Definition: iotypes.h:568
VOID NTAPI ScsiClassReleaseQueue(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:938
long LONG
Definition: pedump.c:60
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
#define IoCompleteRequest
Definition: irp.c:1240
#define SL_OVERRIDE_VERIFY_VOLUME
Definition: iotypes.h:1780
#define MAXIMUM_RETRIES
Definition: class2.h:14
#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:2647
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:2147
ULONG NTAPI DebugPrint(IN PSTRING DebugString, IN ULONG ComponentId, IN ULONG Level)
Definition: debug.c:23
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
unsigned int * PULONG
Definition: retypes.h:1
VOID NTAPI IoFreeIrp(IN PIRP Irp)
Definition: irp.c:1666
struct tagContext Context
Definition: acpixf.h:1030
#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:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
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 3198 of file class2.c.

3227 {
3228  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3229  PCDB cdb;
3230  SCSI_REQUEST_BLOCK srb;
3231  ULONG retries = 1;
3232  NTSTATUS status;
3233 
3234  ASSERT(*(PULONG)deviceExtension != '2slc');
3235 
3236  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
3237 
3238  //
3239  // Build the MODE SENSE CDB.
3240  //
3241 
3242  srb.CdbLength = 6;
3243  cdb = (PCDB)srb.Cdb;
3244 
3245  //
3246  // Set timeout value from device extension.
3247  //
3248 
3249  srb.TimeOutValue = deviceExtension->TimeOutValue;
3250 
3251  cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
3252  cdb->MODE_SENSE.PageCode = PageMode;
3253  cdb->MODE_SENSE.AllocationLength = (UCHAR)Length;
3254 
3255 Retry:
3256 
3258  &srb,
3259  ModeSenseBuffer,
3260  Length,
3261  FALSE);
3262 
3263 
3264  if (status == STATUS_VERIFY_REQUIRED) {
3265 
3266  //
3267  // Routine ScsiClassSendSrbSynchronous does not retry requests returned with
3268  // this status. MODE SENSE commands should be retried anyway.
3269  //
3270 
3271  if (retries--) {
3272 
3273  //
3274  // Retry request.
3275  //
3276 
3277  goto Retry;
3278  }
3279 
3280  } else if (SRB_STATUS(srb.SrbStatus) == SRB_STATUS_DATA_OVERRUN) {
3282  }
3283 
3284  if (NT_SUCCESS(status)) {
3285  return(srb.DataTransferLength);
3286  } else {
3287  return(0);
3288  }
3289 
3290 } // end ScsiClassModeSense()
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
PVOID DeviceExtension
Definition: env_spec_w32.h:418
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: fatprocs.h:1560
unsigned int * PULONG
Definition: retypes.h:1
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
return STATUS_SUCCESS
Definition: btrfs.c:2938
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:1855
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 {
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 media capacity in bytes.
832  //
833 
834  deviceExtension->PartitionLength.QuadPart = (LONGLONG)(lastSector + 1);
835 
836  //
837  // Calculate number of cylinders.
838  //
839 
840  deviceExtension->DiskGeometry->Geometry.Cylinders.QuadPart = (LONGLONG)((lastSector + 1)/(DEFAULT_SECTORS_PER_TRACK * DEFAULT_TRACKS_PER_CYLINDER));
841 
842  deviceExtension->PartitionLength.QuadPart =
843  (deviceExtension->PartitionLength.QuadPart << deviceExtension->SectorShift);
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 
907  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
908 
909  //
910  // This device supports removable media.
911  //
912 
913  deviceExtension->DiskGeometry->Geometry.MediaType = RemovableMedia;
914 
915  } else {
916 
917  //
918  // Assume media type is fixed disk.
919  //
920 
921  deviceExtension->DiskGeometry->Geometry.MediaType = FixedMedia;
922  }
923  }
924 
925  //
926  // Deallocate read capacity buffer.
927  //
928 
929  ExFreePool(readCapacityBuffer);
930 
931  return status;
932 
933 } // 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 FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
#define DEFAULT_SECTORS_PER_TRACK
Definition: class2.c:37
PVOID DeviceExtension
Definition: env_spec_w32.h:418
union _CDB * PCDB
IN PSCSI_REQUEST_BLOCK IN OUT NTSTATUS IN OUT BOOLEAN * Retry
Definition: class2.h:49
int64_t LONGLONG
Definition: typedefs.h:66
#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: fatprocs.h:1560
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:261
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:1855
#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 938 of file class2.c.

962 {
963  PIO_STACK_LOCATION irpStack;
964  PIRP irp;
968  KIRQL currentIrql;
969 
970  ASSERT(*(PULONG)deviceExtension != '2slc');
971 
972  //
973  // Allocate context from nonpaged pool.
974  //
975 
977  sizeof(COMPLETION_CONTEXT));
978 
979  //
980  // Save the device object in the context for use by the completion
981  // routine.
982  //
983 
984  context->DeviceObject = DeviceObject;
985  srb = &context->Srb;
986 
987  //
988  // Zero out srb.
989  //
990 
992 
993  //
994  // Write length to SRB.
995  //
996 
998 
999  //
1000  // Set up SCSI bus address.
1001  //
1002 
1003  srb->PathId = deviceExtension->PathId;
1004  srb->TargetId = deviceExtension->TargetId;
1005  srb->Lun = deviceExtension->Lun;
1006 
1007  //
1008  // If this device is removable then flush the queue. This will also
1009  // release it.
1010  //
1011 
1012  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
1013 
1015 
1016  } else {
1017 
1019 
1020  }
1021 
1022  //
1023  // Build the asynchronous request to be sent to the port driver.
1024  //
1025 
1027 
1028  if(irp == NULL) {
1029 
1030  //
1031  // We have no better way of dealing with this at the moment
1032  //
1033 
1034  KeBugCheck((ULONG)0x0000002DL);
1035 
1036  }
1037 
1040  context,
1041  TRUE,
1042  TRUE,
1043  TRUE);
1044 
1045  irpStack = IoGetNextIrpStackLocation(irp);
1046 
1047  irpStack->MajorFunction = IRP_MJ_SCSI;
1048 
1049  srb->OriginalRequest = irp;
1050 
1051  //
1052  // Store the SRB address in next stack for port driver.
1053  //
1054 
1055  irpStack->Parameters.Scsi.Srb = srb;
1056 
1057  //
1058  // Since this routine can cause outstanding requests to be completed, and
1059  // calling a completion routine at < DISPATCH_LEVEL is dangerous (if they
1060  // call IoStartNextPacket we will bugcheck) raise up to dispatch level before
1061  // issuing the request
1062  //
1063 
1064  currentIrql = KeGetCurrentIrql();
1065 
1066  if(currentIrql < DISPATCH_LEVEL) {
1067  KeRaiseIrql(DISPATCH_LEVEL, &currentIrql);
1068  IoCallDriver(deviceExtension->PortDeviceObject, irp);
1069  KeLowerIrql(currentIrql);
1070  } else {
1071  IoCallDriver(deviceExtension->PortDeviceObject, irp);
1072  }
1073 
1074  return;
1075 
1076 } // end ScsiClassReleaseQueue()
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
#define TRUE
Definition: types.h:120
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
PVOID OriginalRequest
Definition: srb.h:258
Definition: http.c:7098
NTSTATUS NTAPI ScsiClassAsynchronousCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
Definition: class2.c:1216
#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:515
#define IRP_MJ_SCSI
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define FILE_REMOVABLE_MEDIA
Definition: nt_native.h:807
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI KeBugCheck(ULONG BugCheckCode)
Definition: bug.c:1507
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:2647
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
UCHAR PathId
Definition: srb.h:245
#define SCSI_REQUEST_BLOCK_SIZE
Definition: srb.h:274
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:2480
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
PIRP NTAPI IoAllocateIrp(IN CCHAR StackSize, IN BOOLEAN ChargeQuota)
Definition: irp.c:615
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772

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 3369 of file class2.c.

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

Referenced by ScsiClassDeviceControl(), and ScsiDiskDeviceControl().

◆ ScsiClassSendSrbSynchronous()

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

Definition at line 1855 of file class2.c.

1891 {
1892  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
1893  IO_STATUS_BLOCK ioStatus;
1894  ULONG controlType, mjFunction;
1895  PIRP irp;
1896  PIO_STACK_LOCATION irpStack;
1897  KEVENT event;
1898  PUCHAR senseInfoBuffer;
1899  ULONG retryCount = MAXIMUM_RETRIES;
1900  NTSTATUS status;
1901  BOOLEAN retry;
1903 
1904  PAGED_CODE();
1905 
1906  ASSERT(*(PULONG)deviceExtension != '2slc');
1907 
1908  dummy.QuadPart = 0;
1909 
1910  //
1911  // Write length to SRB.
1912  //
1913 
1914  Srb->Length = SCSI_REQUEST_BLOCK_SIZE;
1915 
1916  //
1917  // Set SCSI bus address.
1918  //
1919 
1920  Srb->PathId = deviceExtension->PathId;
1921  Srb->TargetId = deviceExtension->TargetId;
1922  Srb->Lun = deviceExtension->Lun;
1923  Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
1924 
1925  //
1926  // NOTICE: The SCSI-II specification indicates that this field should be
1927  // zero; however, some target controllers ignore the logical unit number
1928  // in the IDENTIFY message and only look at the logical unit number field
1929  // in the CDB.
1930  //
1931 
1932  Srb->Cdb[1] |= deviceExtension->Lun << 5;
1933 
1934  //
1935  // Enable auto request sense.
1936  //
1937 
1938  Srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
1939 
1940  //
1941  // Sense buffer is in aligned nonpaged pool.
1942  //
1943 
1945 
1946  if (senseInfoBuffer == NULL) {
1947 
1948  DebugPrint((1,
1949  "ScsiClassSendSrbSynchronous: Can't allocate request sense buffer\n"));
1951  }
1952 
1953  Srb->SenseInfoBuffer = senseInfoBuffer;
1954  Srb->DataBuffer = BufferAddress;
1955 
1956  //
1957  // Start retries here.
1958  //
1959 
1960 retry:
1961 
1962  //
1963  // Set the event object to the unsignaled state.
1964  // It will be used to signal request completion.
1965  //
1966 
1968 
1969  //
1970  // Set controlType and Srb direction flags.
1971  //
1972 
1973  if (BufferAddress != NULL) {
1974 
1975  if (WriteToDevice) {
1976 
1977  controlType = IOCTL_SCSI_EXECUTE_OUT;
1978  Srb->SrbFlags = SRB_FLAGS_DATA_OUT;
1979  mjFunction = IRP_MJ_WRITE;
1980 
1981  } else {
1982 
1983  controlType = IOCTL_SCSI_EXECUTE_IN;
1984  Srb->SrbFlags = SRB_FLAGS_DATA_IN;
1985  mjFunction = IRP_MJ_READ;
1986  }
1987 
1988  } else {
1989 
1990  BufferLength = 0;
1991  controlType = IOCTL_SCSI_EXECUTE_NONE;
1992  Srb->SrbFlags = SRB_FLAGS_NO_DATA_TRANSFER;
1993  mjFunction = IRP_MJ_FLUSH_BUFFERS;
1994  }
1995 
1996  //
1997  // Build device I/O control request with data transfer.
1998  //
2000  mjFunction,
2001  deviceExtension->DeviceObject,
2002  BufferAddress,
2003  (BufferAddress) ? BufferLength : 0,
2004  &dummy,
2005  &ioStatus);
2006 
2007  if (irp == NULL) {
2008  ExFreePool(senseInfoBuffer);
2009  DebugPrint((1, "ScsiClassSendSrbSynchronous: Can't allocate Irp\n"));
2011  }
2012 
2013  // Set event field
2014  irp->UserEvent = &event;
2015 
2016  //
2017  // Disable synchronous transfer for these requests.
2018  //
2019 
2021 
2022  //
2023  // Set the transfer length.
2024  //
2025 
2026  Srb->DataTransferLength = BufferLength;
2027 
2028  //
2029  // Zero out status.
2030  //
2031 
2032  Srb->ScsiStatus = Srb->SrbStatus = 0;
2033  Srb->NextSrb = 0;
2034 
2035  // Set completion routine
2037  irp,
2039  NULL,
2040  TRUE,
2041  TRUE,
2042  TRUE);
2043 
2044  //
2045  // Get next stack location.
2046  //
2047 
2048  irpStack = IoGetNextIrpStackLocation(irp);
2049 
2051  irpStack->Parameters.DeviceIoControl.IoControlCode = controlType;
2052 
2053  //
2054  // Set up SRB for execute scsi request. Save SRB address in next stack
2055  // for the port driver.
2056  //
2057 
2058  irpStack->Parameters.Scsi.Srb = Srb;
2059 
2060  //
2061  // Set up IRP Address.
2062  //
2063 
2064  Srb->OriginalRequest = irp;
2065 
2066  //
2067  // Call the port driver with the request and wait for it to complete.
2068  //
2069 
2070  status = IoCallDriver(deviceExtension->PortDeviceObject, irp);
2071 
2072  if (status == STATUS_PENDING) {
2074  }
2075 
2076  //
2077  // Check that request completed without error.
2078  //
2079 
2080  if (SRB_STATUS(Srb->SrbStatus) != SRB_STATUS_SUCCESS) {
2081 
2082  //
2083  // Release the queue if it is frozen.
2084  //
2085 
2086  if (Srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
2088  }
2089 
2090  //
2091  // Update status and determine if request should be retried.
2092  //
2093 
2095  Srb,
2096  IRP_MJ_SCSI,
2097  0,
2098  MAXIMUM_RETRIES - retryCount,
2099  &status);
2100 
2101  if (retry) {
2102 
2103  if ((status == STATUS_DEVICE_NOT_READY && ((PSENSE_DATA) senseInfoBuffer)
2104  ->AdditionalSenseCode == SCSI_ADSENSE_LUN_NOT_READY) ||
2105  SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_SELECTION_TIMEOUT) {
2106 
2108 
2109  //
2110  // Delay for 2 seconds.
2111  //
2112 
2113  delay.QuadPart = (LONGLONG)( - 10 * 1000 * 1000 * 2 );
2114 
2115  //
2116  // Stall for a while to let the controller spinup.
2117  //
2118 
2120  FALSE,
2121  &delay);
2122 
2123  }
2124 
2125  //
2126  // If retries are not exhausted then retry this operation.
2127  //
2128 
2129  if (retryCount--) {
2130  goto retry;
2131  }
2132  }
2133 
2134  } else {
2135 
2137  }
2138 
2139  ExFreePool(senseInfoBuffer);
2140  return status;
2141 
2142 } // end ScsiClassSendSrbSynchronous()
#define IOCTL_SCSI_EXECUTE_OUT
Definition: cdrw_hw.h:1452
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
PVOID OriginalRequest
Definition: srb.h:258
#define IRP_MJ_FLUSH_BUFFERS
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 PAGED_CODE()
Definition: video.h:57
#define IoSetCompletionRoutine(_Irp, _CompletionRoutine, _Context, _InvokeOnSuccess, _InvokeOnError, _InvokeOnCancel)
Definition: irp.cpp:515
#define IRP_MJ_SCSI
VOID NTAPI ScsiClassReleaseQueue(IN PDEVICE_OBJECT DeviceObject)
Definition: class2.c:938
_In_ ULONG BufferLength
Definition: usbdlib.h:225
NTSTATUS NTAPI KeDelayExecutionThread(IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Interval OPTIONAL)
Definition: wait.c:283
PVOID DeviceExtension
Definition: env_spec_w32.h:418
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:4974
#define MAXIMUM_RETRIES
Definition: class2.h:14
int64_t LONGLONG
Definition: typedefs.h:66
#define STATUS_PENDING
Definition: ntstatus.h:82
#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
void delay(unsigned msec)
Definition: i386rtl.c:32
#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:2647
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:2147
#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
#define IOCTL_SCSI_EXECUTE_NONE
Definition: cdrw_hw.h:1453
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#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
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:2772
return STATUS_SUCCESS
Definition: btrfs.c:2938
static SERVICE_STATUS status
Definition: service.c:31
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define STATUS_DEVICE_NOT_READY
Definition: shellext.h:70
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 1297 of file class2.c.

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

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