ReactOS  0.4.14-dev-52-g6116262
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 1531 of file class2.c.

1560 {
1562  PSCSI_REQUEST_BLOCK srb;
1563 
1564  srb = &context->Srb;
1565 
1566  //
1567  // If this is an execute srb, then check the return status and make sure.
1568  // the queue is not frozen.
1569  //
1570 
1571  if (srb->Function == SRB_FUNCTION_EXECUTE_SCSI) {
1572 
1573  //
1574  // Check for a frozen queue.
1575  //
1576 
1577  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
1578 
1579  //
1580  // Unfreeze the queue getting the device object from the context.
1581  //
1582 
1583  ScsiClassReleaseQueue(context->DeviceObject);
1584  }
1585  }
1586 
1587  //
1588  // Free the context and the Irp.
1589  //
1590 
1591  if (Irp->MdlAddress != NULL) {
1592  MmUnlockPages(Irp->MdlAddress);
1593  IoFreeMdl(Irp->MdlAddress);
1594 
1595  Irp->MdlAddress = NULL;
1596  }
1597 
1599  IoFreeIrp(Irp);
1600 
1601  //
1602  // Indicate the I/O system should stop processing the Irp completion.
1603  //
1604 
1606 
1607 } // ScsiClassAsynchronousCompletion()
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
Definition: http.c:6587
_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:1253
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:1024
#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 3284 of file class2.c.

3318 {
3319  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3322  LARGE_INTEGER startingOffset = currentIrpStack->Parameters.Read.ByteOffset;
3323  PSCSI_REQUEST_BLOCK srb;
3324  PCDB cdb;
3325  ULONG logicalBlockAddress;
3326  USHORT transferBlocks;
3327 
3328  ASSERT(*(PULONG)deviceExtension != '2slc');
3329 
3330  //
3331  // Calculate relative sector address.
3332  //
3333 
3334  logicalBlockAddress = (ULONG)(Int64ShrlMod32(startingOffset.QuadPart, deviceExtension->SectorShift));
3335 
3336  //
3337  // Allocate an Srb.
3338  //
3339 
3340  srb = ExAllocateFromNPagedLookasideList(&deviceExtension->SrbLookasideListHead);
3341 
3342  srb->SrbFlags = 0;
3343 
3344  //
3345  // Write length to SRB.
3346  //
3347 
3349 
3350  //
3351  // Set up IRP Address.
3352  //
3353 
3354  srb->OriginalRequest = Irp;
3355 
3356  //
3357  // Set up target ID and logical unit number.
3358  //
3359 
3360  srb->PathId = deviceExtension->PathId;
3361  srb->TargetId = deviceExtension->TargetId;
3362  srb->Lun = deviceExtension->Lun;
3364  srb->DataBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
3365 
3366  //
3367  // Save byte count of transfer in SRB Extension.
3368  //
3369 
3370  srb->DataTransferLength = currentIrpStack->Parameters.Read.Length;
3371 
3372  //
3373  // Initialize the queue actions field.
3374  //
3375 
3377 
3378  //
3379  // Queue sort key is Relative Block Address.
3380  //
3381 
3382  srb->QueueSortKey = logicalBlockAddress;
3383 
3384  //
3385  // Indicate auto request sense by specifying buffer and size.
3386  //
3387 
3388  srb->SenseInfoBuffer = deviceExtension->SenseData;
3390 
3391  //
3392  // Set timeout value of one unit per 64k bytes of data.
3393  //
3394 
3395  srb->TimeOutValue = ((srb->DataTransferLength + 0xFFFF) >> 16) *
3396  deviceExtension->TimeOutValue;
3397 
3398  //
3399  // Zero statuses.
3400  //
3401 
3402  srb->SrbStatus = srb->ScsiStatus = 0;
3403  srb->NextSrb = 0;
3404 
3405  //
3406  // Indicate that 10-byte CDB's will be used.
3407  //
3408 
3409  srb->CdbLength = 10;
3410 
3411  //
3412  // Fill in CDB fields.
3413  //
3414 
3415  cdb = (PCDB)srb->Cdb;
3416 
3417  //
3418  // Zero 12 bytes for Atapi Packets
3419  //
3420 
3422 
3423  cdb->CDB10.LogicalUnitNumber = deviceExtension->Lun;
3424  transferBlocks = (USHORT)(currentIrpStack->Parameters.Read.Length >> deviceExtension->SectorShift);
3425 
3426  //
3427  // Move little endian values into CDB in big endian format.
3428  //
3429 
3430  cdb->CDB10.LogicalBlockByte0 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte3;
3431  cdb->CDB10.LogicalBlockByte1 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte2;
3432  cdb->CDB10.LogicalBlockByte2 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte1;
3433  cdb->CDB10.LogicalBlockByte3 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte0;
3434 
3435  cdb->CDB10.TransferBlocksMsb = ((PFOUR_BYTE)&transferBlocks)->Byte1;
3436  cdb->CDB10.TransferBlocksLsb = ((PFOUR_BYTE)&transferBlocks)->Byte0;
3437 
3438  //
3439  // Set transfer direction flag and Cdb command.
3440  //
3441 
3442  if (currentIrpStack->MajorFunction == IRP_MJ_READ) {
3443 
3444  DebugPrint((3, "ScsiClassBuildRequest: Read Command\n"));
3445 
3446  srb->SrbFlags |= SRB_FLAGS_DATA_IN;
3447  cdb->CDB10.OperationCode = SCSIOP_READ;
3448 
3449  } else {
3450 
3451  DebugPrint((3, "ScsiClassBuildRequest: Write Command\n"));
3452 
3453  srb->SrbFlags |= SRB_FLAGS_DATA_OUT;
3454  cdb->CDB10.OperationCode = SCSIOP_WRITE;
3455  }
3456 
3457  //
3458  // If this is not a write-through request, then allow caching.
3459  //
3460 
3461  if (!(currentIrpStack->Flags & SL_WRITE_THROUGH)) {
3462 
3464 
3465  } else {
3466 
3467  //
3468  // If write caching is enable then force media access in the
3469  // cdb.
3470  //
3471 
3472  if (deviceExtension->DeviceFlags & DEV_WRITE_CACHE) {
3473  cdb->CDB10.ForceUnitAccess = TRUE;
3474  }
3475  }
3476 
3477  //
3478  // Or in the default flags from the device object.
3479  //
3480 
3481  srb->SrbFlags |= deviceExtension->SrbFlags;
3482 
3483  //
3484  // Set up major SCSI function.
3485  //
3486 
3487  nextIrpStack->MajorFunction = IRP_MJ_SCSI;
3488 
3489  //
3490  // Save SRB address in next stack for port driver.
3491  //
3492 
3493  nextIrpStack->Parameters.Scsi.Srb = srb;
3494 
3495  //
3496  // Save retry count in current IRP stack.
3497  //
3498 
3499  currentIrpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
3500 
3501  //
3502  // Set up IoCompletion routine address.
3503  //
3504 
3506 
3507  return;
3508 
3509 } // 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:1806
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 4740 of file class2.c.

4771 {
4772  IO_STATUS_BLOCK ioStatus;
4773  PIRP irp;
4774  PIO_STACK_LOCATION irpStack;
4775  KEVENT event;
4776  NTSTATUS status;
4777  SCSI_REQUEST_BLOCK srb;
4778 
4779  PAGED_CODE();
4780 
4781  if (NewPortDeviceObject != NULL) {
4782  *NewPortDeviceObject = NULL;
4783  }
4784 
4785  //
4786  // Clear the SRB fields.
4787  //
4788 
4789  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
4790 
4791  //
4792  // Write length to SRB.
4793  //
4794 
4796 
4797  //
4798  // Set SCSI bus address.
4799  //
4800 
4801  srb.PathId = LunInfo->PathId;
4802  srb.TargetId = LunInfo->TargetId;
4803  srb.Lun = LunInfo->Lun;
4804 
4807 
4808  //
4809  // Set the event object to the unsignaled state.
4810  // It will be used to signal request completion.
4811  //
4812 
4814 
4815  //
4816  // Build synchronous request with no transfer.
4817  //
4818 
4820  PortDeviceObject,
4821  NULL,
4822  0,
4823  NULL,
4824  0,
4825  TRUE,
4826  &event,
4827  &ioStatus);
4828 
4829  if (irp == NULL) {
4830 
4831  DebugPrint((1, "ScsiClassClaimDevice: Can't allocate Irp\n"));
4833  }
4834 
4835  irpStack = IoGetNextIrpStackLocation(irp);
4836 
4837  //
4838  // Save SRB address in next stack for port driver.
4839  //
4840 
4841  irpStack->Parameters.Scsi.Srb = &srb;
4842 
4843  //
4844  // Set up IRP Address.
4845  //
4846 
4847  srb.OriginalRequest = irp;
4848 
4849  //
4850  // Call the port driver with the request and wait for it to complete.
4851  //
4852 
4853  status = IoCallDriver(PortDeviceObject, irp);
4854  if (status == STATUS_PENDING) {
4855 
4857  status = ioStatus.Status;
4858  }
4859 
4860  //
4861  // If this is a release request, then just decrement the reference count
4862  // and return. The status does not matter.
4863  //
4864 
4865  if (Release) {
4866 
4867  //ObDereferenceObject(PortDeviceObject);
4868  return STATUS_SUCCESS;
4869  }
4870 
4871  if (!NT_SUCCESS(status)) {
4872  return status;
4873  }
4874 
4875  ASSERT(srb.DataBuffer != NULL);
4876 
4877  //
4878  // Reference the new port driver object so that it will not go away while
4879  // it is being used.
4880  //
4881 
4883  0,
4884  NULL,
4885  KernelMode );
4886 
4887  if (!NT_SUCCESS(status)) {
4888 
4889  return status;
4890  }
4892 
4893  //
4894  // Return the new port device object pointer.
4895  //
4896 
4897  if (NewPortDeviceObject != NULL) {
4898  *NewPortDeviceObject = srb.DataBuffer;
4899  }
4900 
4901  return status;
4902 }
#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:2966
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ ScsiClassDeviceControl()

NTSTATUS ScsiClassDeviceControl ( PDEVICE_OBJECT  DeviceObject,
PIRP  Irp 
)

Definition at line 3917 of file class2.c.

3943 {
3945  PIO_STACK_LOCATION nextStack;
3946  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3947  PSCSI_REQUEST_BLOCK srb;
3948  PCDB cdb;
3949  NTSTATUS status;
3950  ULONG modifiedIoControlCode;
3951 
3952  ASSERT(*(PULONG)deviceExtension != '2slc');
3953 
3954  if (irpStack->Parameters.DeviceIoControl.IoControlCode ==
3956 
3957  Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
3960  goto SetStatusAndReturn;
3961  }
3962 
3963  //
3964  // If this is a pass through I/O control, set the minor function code
3965  // and device address and pass it to the port driver.
3966  //
3967 
3968  if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_PASS_THROUGH
3969  || irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_PASS_THROUGH_DIRECT) {
3970 
3971  PSCSI_PASS_THROUGH scsiPass;
3972 
3973  nextStack = IoGetNextIrpStackLocation(Irp);
3974 
3975  //
3976  // Validate the user buffer.
3977  //
3978 
3979  if (irpStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(SCSI_PASS_THROUGH)){
3980 
3981  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
3984  goto SetStatusAndReturn;
3985  }
3986 
3987  //
3988  // Force the SCSI address to the correct value.
3989  //
3990 
3991  scsiPass = Irp->AssociatedIrp.SystemBuffer;
3992  scsiPass->PathId = deviceExtension->PathId;
3993  scsiPass->TargetId = deviceExtension->TargetId;
3994  scsiPass->Lun = deviceExtension->Lun;
3995 
3996  //
3997  // NOTICE: The SCSI-II specification indicates that this field
3998  // should be zero; however, some target controllers ignore the logical
3999  // unit number in the IDENTIFY message and only look at the logical
4000  // unit number field in the CDB.
4001  //
4002 
4003  scsiPass->Cdb[1] |= deviceExtension->Lun << 5;
4004 
4005  nextStack->Parameters = irpStack->Parameters;
4006  nextStack->MajorFunction = irpStack->MajorFunction;
4007  nextStack->MinorFunction = IRP_MN_SCSI_CLASS;
4008 
4009  status = IoCallDriver(deviceExtension->PortDeviceObject, Irp);
4010  goto SetStatusAndReturn;
4011  }
4012 
4013  if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SCSI_GET_ADDRESS) {
4014 
4015  PSCSI_ADDRESS scsiAddress = Irp->AssociatedIrp.SystemBuffer;
4016 
4017  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength <
4018  sizeof(SCSI_ADDRESS)) {
4019 
4020  //
4021  // Indicate unsuccessful status and no data transferred.
4022  //
4023 
4024  Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
4025  Irp->IoStatus.Information = 0;
4028  goto SetStatusAndReturn;
4029 
4030  }
4031 
4032  scsiAddress->Length = sizeof(SCSI_ADDRESS);
4033  scsiAddress->PortNumber = deviceExtension->PortNumber;
4034  scsiAddress->PathId = deviceExtension->PathId;
4035  scsiAddress->TargetId = deviceExtension->TargetId;
4036  scsiAddress->Lun = deviceExtension->Lun;
4037  Irp->IoStatus.Information = sizeof(SCSI_ADDRESS);
4038  Irp->IoStatus.Status = STATUS_SUCCESS;
4041  goto SetStatusAndReturn;
4042  }
4043 
4044  if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_MOUNTDEV_QUERY_UNIQUE_ID ||
4045  irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME) {
4046 
4047  UNIMPLEMENTED;
4048  Irp->IoStatus.Information = 0;
4049  Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
4052  goto SetStatusAndReturn;
4053  }
4054 
4055  if (irpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_MOUNTDEV_QUERY_DEVICE_NAME) {
4056 
4057  PMOUNTDEV_NAME name = Irp->AssociatedIrp.SystemBuffer;
4058 
4059  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(MOUNTDEV_NAME)) {
4060 
4061  Irp->IoStatus.Information = 0;
4062  Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
4065  goto SetStatusAndReturn;
4066  }
4067 
4068  RtlZeroMemory(name, sizeof(MOUNTDEV_NAME));
4069  name->NameLength = deviceExtension->DeviceName.Length;
4070 
4071  if (irpStack->Parameters.DeviceIoControl.OutputBufferLength < FIELD_OFFSET(MOUNTDEV_NAME, Name) + name->NameLength) {
4072 
4073  Irp->IoStatus.Information = sizeof(MOUNTDEV_NAME);
4074  Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
4077  goto SetStatusAndReturn;
4078  }
4079 
4080  RtlCopyMemory(name->Name, deviceExtension->DeviceName.Buffer,
4081  name->NameLength);
4083  Irp->IoStatus.Status = STATUS_SUCCESS;
4084  Irp->IoStatus.Information = FIELD_OFFSET(MOUNTDEV_NAME, Name) + name->NameLength;
4086  goto SetStatusAndReturn;
4087  }
4088 
4090 
4091  if (srb == NULL) {
4092 
4093  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
4096  goto SetStatusAndReturn;
4097  }
4098 
4099  //
4100  // Write zeros to Srb.
4101  //
4102 
4104 
4105  cdb = (PCDB)srb->Cdb;
4106 
4107  //
4108  // Change the device type to disk for the switch statement.
4109  //
4110 
4111  modifiedIoControlCode = (irpStack->Parameters.DeviceIoControl.IoControlCode
4112  & ~0xffff0000) | (IOCTL_DISK_BASE << 16);
4113 
4114  switch (modifiedIoControlCode) {
4115 
4116  case IOCTL_DISK_CHECK_VERIFY: {
4117 
4118  PIRP irp2 = NULL;
4119  PIO_STACK_LOCATION newStack;
4120 
4121  DebugPrint((1,"ScsiDeviceIoControl: Check verify\n"));
4122 
4123  //
4124  // If a buffer for a media change count was provided, make sure it's
4125  // big enough to hold the result
4126  //
4127 
4128  if(irpStack->Parameters.DeviceIoControl.OutputBufferLength) {
4129 
4130  //
4131  // If the buffer is too small to hold the media change count
4132  // then return an error to the caller
4133  //
4134 
4135  if(irpStack->Parameters.DeviceIoControl.OutputBufferLength <
4136  sizeof(ULONG)) {
4137 
4138  DebugPrint((3,"ScsiDeviceIoControl: media count "
4139  "buffer too small\n"));
4140 
4141  Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
4142  Irp->IoStatus.Information = 0;
4143  ExFreePool(srb);
4146  goto SetStatusAndReturn;
4147 
4148  }
4149 
4150  //
4151  // The caller has provided a valid buffer. Allocate an additional
4152  // irp and stick the CheckVerify completion routine on it. We will
4153  // then send this down to the port driver instead of the irp the
4154  // caller sent in
4155  //
4156 
4157  DebugPrint((2,"ScsiDeviceIoControl: Check verify wants "
4158  "media count\n"));
4159 
4160  //
4161  // Allocate a new irp to send the TestUnitReady to the port driver
4162  //
4163 
4164  irp2 = IoAllocateIrp((CCHAR) (DeviceObject->StackSize + 3), FALSE);
4165 
4166  if(irp2 == NULL) {
4167  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
4168  Irp->IoStatus.Information = 0;
4169  ExFreePool(srb);
4172  goto SetStatusAndReturn;
4173  }
4174 
4175  irp2->Tail.Overlay.Thread = Irp->Tail.Overlay.Thread;
4177 
4178  //
4179  // Set the top stack location and shove the master Irp into the
4180  // top location
4181  //
4182 
4183  newStack = IoGetCurrentIrpStackLocation(irp2);
4184  newStack->Parameters.Others.Argument1 = Irp;
4185  newStack->DeviceObject = DeviceObject;
4186 
4187  //
4188  // Stick the check verify completion routine onto the stack
4189  // and prepare the irp for the port driver
4190  //
4191 
4194  NULL,
4195  TRUE,
4196  TRUE,
4197  TRUE);
4198 
4200  newStack = IoGetCurrentIrpStackLocation(irp2);
4201  newStack->DeviceObject = DeviceObject;
4202 
4203  //
4204  // Mark the master irp as pending - whether the lower level
4205  // driver completes it immediately or not this should allow it
4206  // to go all the way back up.
4207  //
4208 
4210 
4211  Irp = irp2;
4212 
4213  }
4214 
4215  //
4216  // Test Unit Ready
4217  //
4218 
4219  srb->CdbLength = 6;
4220  cdb->CDB6GENERIC.OperationCode = SCSIOP_TEST_UNIT_READY;
4221 
4222  //
4223  // Set timeout value.
4224  //
4225 
4226  srb->TimeOutValue = deviceExtension->TimeOutValue;
4227 
4228  //
4229  // Since this routine will always hand the request to the
4230  // port driver if there isn't a data transfer to be done
4231  // we don't have to worry about completing the request here
4232  // on an error
4233  //
4234 
4236  srb,
4237  Irp,
4238  NULL,
4239  0,
4240  FALSE);
4241 
4242  break;
4243  }
4244 
4245  case IOCTL_DISK_MEDIA_REMOVAL: {
4246 
4247  PPREVENT_MEDIA_REMOVAL MediaRemoval = Irp->AssociatedIrp.SystemBuffer;
4248 
4249  //
4250  // Prevent/Allow media removal.
4251  //
4252 
4253  DebugPrint((3,"DiskIoControl: Prevent/Allow media removal\n"));
4254 
4255  if (irpStack->Parameters.DeviceIoControl.InputBufferLength <
4256  sizeof(PREVENT_MEDIA_REMOVAL)) {
4257 
4258  //
4259  // Indicate unsuccessful status and no data transferred.
4260  //
4261 
4262  Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
4263  Irp->IoStatus.Information = 0;
4264  ExFreePool(srb);
4267  goto SetStatusAndReturn;
4268  }
4269 
4270  //
4271  // Get physical device extension. This is where the
4272  // lock count is stored.
4273  //
4274 
4275  deviceExtension = deviceExtension->PhysicalDevice->DeviceExtension;
4276 
4277  //
4278  // If command succeeded then increment or decrement lock counter.
4279  //
4280 
4281  if (MediaRemoval->PreventMediaRemoval) {
4282 
4283  //
4284  // This is a lock command. Reissue the command in case bus or device
4285  // was reset and lock cleared.
4286  //
4287 
4288  InterlockedIncrement(&deviceExtension->LockCount);
4289 
4290  DebugPrint((1,
4291  "ScsiClassDeviceControl: Lock media, lock count %x on disk %x\n",
4292  deviceExtension->LockCount,
4293  deviceExtension->DeviceNumber));
4294 
4295  } else {
4296 
4297  //
4298  // This is an unlock command.
4299  //
4300 
4301  if (!deviceExtension->LockCount ||
4302  (InterlockedDecrement(&deviceExtension->LockCount) != 0)) {
4303 
4304  DebugPrint((1,
4305  "ScsiClassDeviceControl: Unlock media, lock count %x on disk %x\n",
4306  deviceExtension->LockCount,
4307  deviceExtension->DeviceNumber));
4308 
4309  //
4310  // Don't unlock because someone still wants it locked.
4311  //
4312 
4313  Irp->IoStatus.Status = STATUS_SUCCESS;
4314  ExFreePool(srb);
4317  goto SetStatusAndReturn;
4318  }
4319 
4320  DebugPrint((1,
4321  "ScsiClassDeviceControl: Unlock media, lock count %x on disk %x\n",
4322  deviceExtension->LockCount,
4323  deviceExtension->DeviceNumber));
4324  }
4325 
4326  srb->CdbLength = 6;
4327 
4328  cdb->MEDIA_REMOVAL.OperationCode = SCSIOP_MEDIUM_REMOVAL;
4329 
4330  //
4331  // TRUE - prevent media removal.
4332  // FALSE - allow media removal.
4333  //
4334 
4335  cdb->MEDIA_REMOVAL.Prevent = MediaRemoval->PreventMediaRemoval;
4336 
4337  //
4338  // Set timeout value.
4339  //
4340 
4341  srb->TimeOutValue = deviceExtension->TimeOutValue;
4343  srb,
4344  Irp,
4345  NULL,
4346  0,
4347  FALSE);
4348 
4349  //
4350  // Some devices will not support lock/unlock.
4351  // Pretend that it worked.
4352  //
4353 
4354  break;
4355  }
4356 
4357  case IOCTL_DISK_RESERVE: {
4358 
4359  //
4360  // Reserve logical unit.
4361  //
4362 
4363  srb->CdbLength = 6;
4364 
4365  cdb->CDB6GENERIC.OperationCode = SCSIOP_RESERVE_UNIT;
4366 
4367  //
4368  // Set timeout value.
4369  //
4370 
4371  srb->TimeOutValue = deviceExtension->TimeOutValue;
4372 
4374  srb,
4375  Irp,
4376  NULL,
4377  0,
4378  FALSE);
4379 
4380  break;
4381  }
4382 
4383  case IOCTL_DISK_RELEASE: {
4384 
4385  //
4386  // Release logical unit.
4387  //
4388 
4389  srb->CdbLength = 6;
4390 
4391  cdb->CDB6GENERIC.OperationCode = SCSIOP_RELEASE_UNIT;
4392 
4393  //
4394  // Set timeout value.
4395  //
4396 
4397  srb->TimeOutValue = deviceExtension->TimeOutValue;
4398 
4400  srb,
4401  Irp,
4402  NULL,
4403  0,
4404  FALSE);
4405 
4406  break;
4407  }
4408 
4409  case IOCTL_DISK_EJECT_MEDIA: {
4410 
4411  //
4412  // Eject media.
4413  //
4414 
4415  srb->CdbLength = 6;
4416 
4417  cdb->START_STOP.OperationCode = SCSIOP_START_STOP_UNIT;
4418  cdb->START_STOP.LoadEject = 1;
4419  cdb->START_STOP.Start = 0;
4420 
4421  //
4422  // Set timeout value.
4423  //
4424 
4425  srb->TimeOutValue = deviceExtension->TimeOutValue;
4427  srb,
4428  Irp,
4429  NULL,
4430  0,
4431  FALSE);
4432  break;
4433  }
4434 
4435  case IOCTL_DISK_LOAD_MEDIA: {
4436 
4437  //
4438  // Load media.
4439  //
4440 
4441  DebugPrint((3,"CdRomDeviceControl: Load media\n"));
4442 
4443  srb->CdbLength = 6;
4444 
4445  cdb->START_STOP.OperationCode = SCSIOP_START_STOP_UNIT;
4446  cdb->START_STOP.LoadEject = 1;
4447  cdb->START_STOP.Start = 1;
4448 
4449  //
4450  // Set timeout value.
4451  //
4452 
4453  srb->TimeOutValue = deviceExtension->TimeOutValue;
4455  srb,
4456  Irp,
4457  NULL,
4458  0,
4459  FALSE);
4460 
4461  break;
4462  }
4463 
4465 
4466  //
4467  // Search for devices that have been powered on since the last
4468  // device search or system initialization.
4469  //
4470 
4471  DebugPrint((3,"CdRomDeviceControl: Find devices\n"));
4472  status = DriverEntry(DeviceObject->DriverObject,
4473  NULL);
4474 
4475  Irp->IoStatus.Status = status;
4476  ExFreePool(srb);
4478 
4479  break;
4480  }
4481 
4482  default: {
4483 
4484  DebugPrint((3,"ScsiIoDeviceControl: Unsupported device IOCTL\n"));
4485 
4486  //
4487  // Pass the device control to the next driver.
4488  //
4489 
4490  ExFreePool(srb);
4491 
4492  //
4493  // Copy the Irp stack parameters to the next stack location.
4494  //
4495 
4496  nextStack = IoGetNextIrpStackLocation(Irp);
4497  nextStack->Parameters = irpStack->Parameters;
4498  nextStack->MajorFunction = irpStack->MajorFunction;
4499  nextStack->MinorFunction = irpStack->MinorFunction;
4500 
4501  status = IoCallDriver(deviceExtension->PortDeviceObject, Irp);
4502  break;
4503  }
4504 
4505  } // end switch( ...
4506 
4507 SetStatusAndReturn:
4508 
4509  return status;
4510 }
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
#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:64
#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:5161
NTSTATUS NTAPI DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
Definition: class2.c:130
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
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:3684
#define InterlockedIncrement
Definition: armddk.h:53
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
#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:36
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:2966
IoMarkIrpPending(Irp)
static SERVICE_STATUS status
Definition: service.c:31
#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 846 of file class2.c.

875 {
876  PIRP irp;
877  IO_STATUS_BLOCK ioStatus;
878  KEVENT event;
880 
881  PAGED_CODE();
882 
883  //
884  // Create notification event object to be used to signal the
885  // request completion.
886  //
887 
889 
890  //
891  // Build the synchronous request to be sent to the port driver
892  // to perform the request.
893  //
894 
896  PortDeviceObject,
897  NULL,
898  0,
899  PortCapabilities,
900  sizeof(PVOID),
901  FALSE,
902  &event,
903  &ioStatus);
904 
905  if (irp == NULL) {
907  }
908 
909  //
910  // Pass request to port driver and wait for request to complete.
911  //
912 
913  status = IoCallDriver(PortDeviceObject, irp);
914 
915  if (status == STATUS_PENDING) {
917  return(ioStatus.Status);
918  }
919 
920  return status;
921 
922 } // 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 4907 of file class2.c.

4936 {
4938  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
4939  PSCSI_REQUEST_BLOCK srb;
4940 
4941  ASSERT(*(PULONG)deviceExtension != '2slc');
4942 
4943  //
4944  // Get a pointer to the SRB.
4945  //
4946 
4947  srb = irpStack->Parameters.Scsi.Srb;
4948 
4949  //
4950  // Set SCSI bus address.
4951  //
4952 
4953  srb->PathId = deviceExtension->PathId;
4954  srb->TargetId = deviceExtension->TargetId;
4955  srb->Lun = deviceExtension->Lun;
4956 
4957  //
4958  // NOTICE: The SCSI-II specification indicates that this field should be
4959  // zero; however, some target controllers ignore the logical unit number
4960  // in the IDENTIFY message and only look at the logical unit number field
4961  // in the CDB.
4962  //
4963 
4964  srb->Cdb[1] |= deviceExtension->Lun << 5;
4965 
4966  //
4967  // Set the parameters in the next stack location.
4968  //
4969 
4970  irpStack = IoGetNextIrpStackLocation(Irp);
4971 
4972  irpStack->Parameters.Scsi.Srb = srb;
4973  irpStack->MajorFunction = IRP_MJ_SCSI;
4974  irpStack->MinorFunction = IRP_MN_SCSI_CLASS;
4975 
4977  return IoCallDriver(deviceExtension->PortDeviceObject, Irp);
4978 }
#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:4982
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 2462 of file class2.c.

2498 {
2499  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
2500  PDEVICE_EXTENSION physicalExtension = deviceExtension->PhysicalDevice->DeviceExtension;
2501  PSENSE_DATA senseBuffer = Srb->SenseInfoBuffer;
2502  BOOLEAN retry = TRUE;
2503  BOOLEAN logError = FALSE;
2504  ULONG badSector = 0;
2505  ULONG uniqueId = 0;
2506  NTSTATUS logStatus;
2507  ULONG readSector;
2508  ULONG index;
2509  PIO_ERROR_LOG_PACKET errorLogEntry;
2510 #if DBG
2511  ULONG i;
2512 #endif
2513 
2514  ASSERT(*(PULONG)deviceExtension != '2slc');
2515 
2516  //
2517  // Check that request sense buffer is valid.
2518  //
2519 
2520 #if DBG
2521  DebugPrint((3, "Opcode %x\nParameters: ",Srb->Cdb[0]));
2522  for (i = 1; i < 12; i++) {
2523  DebugPrint((3,"%x ",Srb->Cdb[i]));
2524  }
2525  DebugPrint((3,"\n"));
2526 #endif
2527 
2528  if (Srb->SrbStatus & SRB_STATUS_AUTOSENSE_VALID &&
2529  Srb->SenseInfoBufferLength >= FIELD_OFFSET(SENSE_DATA, CommandSpecificInformation)) {
2530 
2531  DebugPrint((1,"ScsiClassInterpretSenseInfo: Error code is %x\n",
2532  senseBuffer->ErrorCode));
2533  DebugPrint((1,"ScsiClassInterpretSenseInfo: Sense key is %x\n",
2534  senseBuffer->SenseKey));
2535  DebugPrint((1, "ScsiClassInterpretSenseInfo: Additional sense code is %x\n",
2536  senseBuffer->AdditionalSenseCode));
2537  DebugPrint((1, "ScsiClassInterpretSenseInfo: Additional sense code qualifier is %x\n",
2538  senseBuffer->AdditionalSenseCodeQualifier));
2539 
2540  //
2541  // Zero the additional sense code and additional sense code qualifier
2542  // if they were not returned by the device.
2543  //
2544 
2545  readSector = senseBuffer->AdditionalSenseLength +
2546  FIELD_OFFSET(SENSE_DATA, AdditionalSenseLength);
2547 
2548  if (readSector > Srb->SenseInfoBufferLength) {
2549  readSector = Srb->SenseInfoBufferLength;
2550  }
2551 
2552  if (readSector <= FIELD_OFFSET(SENSE_DATA, AdditionalSenseCode)) {
2553  senseBuffer->AdditionalSenseCode = 0;
2554  }
2555 
2556  if (readSector <= FIELD_OFFSET(SENSE_DATA, AdditionalSenseCodeQualifier)) {
2557  senseBuffer->AdditionalSenseCodeQualifier = 0;
2558  }
2559 
2560  switch (senseBuffer->SenseKey & 0xf) {
2561 
2562  case SCSI_SENSE_NOT_READY:
2563 
2564  DebugPrint((1,"ScsiClassInterpretSenseInfo: Device not ready\n"));
2566 
2567  switch (senseBuffer->AdditionalSenseCode) {
2568 
2570 
2571  DebugPrint((1,"ScsiClassInterpretSenseInfo: Lun not ready\n"));
2572 
2573  switch (senseBuffer->AdditionalSenseCodeQualifier) {
2574 
2576 
2577  DebugPrint((1, "ScsiClassInterpretSenseInfo:"
2578  " In process of becoming ready\n"));
2579  break;
2580 
2582 
2583  DebugPrint((1, "ScsiClassInterpretSenseInfo:"
2584  " Manual intervention required\n"));
2586  retry = FALSE;
2587  break;
2588 
2590 
2591  DebugPrint((1, "ScsiClassInterpretSenseInfo: Format in progress\n"));
2592  retry = FALSE;
2593  break;
2594 
2596 
2597  default:
2598 
2599  DebugPrint((1, "ScsiClassInterpretSenseInfo:"
2600  " Initializing command required\n"));
2601 
2602  //
2603  // This sense code/additional sense code
2604  // combination may indicate that the device
2605  // needs to be started. Send an start unit if this
2606  // is a disk device.
2607  //
2608 
2609  if (deviceExtension->DeviceFlags & DEV_SAFE_START_UNIT) {
2611  }
2612 
2613  break;
2614 
2615  } // end switch (senseBuffer->AdditionalSenseCodeQualifier)
2616 
2617  break;
2618 
2620 
2621  DebugPrint((1,
2622  "ScsiClassInterpretSenseInfo:"
2623  " No Media in device.\n"));
2625  retry = FALSE;
2626 
2627  //
2628  // signal autorun that there isn't any media in the device
2629  //
2630 
2631  if((deviceExtension->MediaChangeEvent != NULL)&&
2632  (!deviceExtension->MediaChangeNoMedia)) {
2633  KeSetEvent(deviceExtension->MediaChangeEvent,
2634  (KPRIORITY) 0,
2635  FALSE);
2636  DebugPrint((0, "ScsiClassInterpretSenseInfo:"
2637  "Detected No Media In Device "
2638  "[irp = 0x%lx]\n", Srb->OriginalRequest));
2639  deviceExtension->MediaChangeNoMedia = TRUE;
2640  }
2641 
2642  break;
2643  } // end switch (senseBuffer->AdditionalSenseCode)
2644 
2645  break;
2646 
2648 
2649  DebugPrint((1, "ScsiClassInterpretSenseInfo: Media write protected\n"));
2651  retry = FALSE;
2652  break;
2653 
2655 
2656  DebugPrint((1,"ScsiClassInterpretSenseInfo: Bad media\n"));
2658 
2659  retry = FALSE;
2660  logError = TRUE;
2661  uniqueId = 256;
2662  logStatus = 0;//IO_ERR_BAD_BLOCK;
2663  break;
2664 
2666 
2667  DebugPrint((1,"ScsiClassInterpretSenseInfo: Hardware error\n"));
2669 
2670  logError = TRUE;
2671  uniqueId = 257;
2672  logStatus = 0;//IO_ERR_CONTROLLER_ERROR;
2673 
2674  break;
2675 
2677 
2678  DebugPrint((1, "ScsiClassInterpretSenseInfo: Illegal SCSI request\n"));
2680 
2681  switch (senseBuffer->AdditionalSenseCode) {
2682 
2684  DebugPrint((1, "ScsiClassInterpretSenseInfo: Illegal command\n"));
2685  retry = FALSE;
2686  break;
2687 
2689  DebugPrint((1, "ScsiClassInterpretSenseInfo: Illegal block address\n"));
2691  retry = FALSE;
2692  break;
2693 
2695  DebugPrint((1,"ScsiClassInterpretSenseInfo: Invalid LUN\n"));
2697  retry = FALSE;
2698  break;
2699 
2701  DebugPrint((1,"ScsiClassInterpretSenseInfo: Music area\n"));
2702  retry = FALSE;
2703  break;
2704 
2706  DebugPrint((1,"ScsiClassInterpretSenseInfo: Data area\n"));
2707  retry = FALSE;
2708  break;
2709 
2711  DebugPrint((1, "ScsiClassInterpretSenseInfo: Volume overflow\n"));
2712  retry = FALSE;
2713  break;
2714 
2716  DebugPrint((1, "ScsiClassInterpretSenseInfo: Invalid CDB\n"));
2717 
2718  //
2719  // Check if write cache enabled.
2720  //
2721 
2722  if (deviceExtension->DeviceFlags & DEV_WRITE_CACHE) {
2723 
2724  //
2725  // Assume FUA is not supported.
2726  //
2727 
2728  deviceExtension->DeviceFlags &= ~DEV_WRITE_CACHE;
2729  retry = TRUE;
2730 
2731  } else {
2732  retry = FALSE;
2733  }
2734 
2735  break;
2736 
2737  } // end switch (senseBuffer->AdditionalSenseCode)
2738 
2739  break;
2740 
2742 
2743  switch (senseBuffer->AdditionalSenseCode) {
2745  DebugPrint((1, "ScsiClassInterpretSenseInfo: Media changed\n"));
2746 
2747  if(deviceExtension->MediaChangeEvent != NULL) {
2748 
2749  KeSetEvent(deviceExtension->MediaChangeEvent,
2750  (KPRIORITY) 0,
2751  FALSE);
2752  DebugPrint((0, "ScsiClassInterpretSenseInfo:"
2753  "New Media Found - Setting MediaChanged event"
2754  " [irp = 0x%lx]\n", Srb->OriginalRequest));
2755  deviceExtension->MediaChangeNoMedia = FALSE;
2756 
2757  }
2758  break;
2759 
2761  DebugPrint((1,"ScsiClassInterpretSenseInfo: Bus reset\n"));
2762  break;
2763 
2764  default:
2765  DebugPrint((1,"ScsiClassInterpretSenseInfo: Unit attention\n"));
2766  break;
2767 
2768  } // end switch (senseBuffer->AdditionalSenseCode)
2769 
2770  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA &&
2771  DeviceObject->Vpb->Flags & VPB_MOUNTED) {
2772 
2773  //
2774  // Set bit to indicate that media may have changed
2775  // and volume needs verification.
2776  //
2777 
2779 
2781  retry = FALSE;
2782 
2783  } else {
2784 
2786 
2787  }
2788 
2789  //
2790  // A media change may have occured so increment the change
2791  // count for the physical device
2792  //
2793 
2794  physicalExtension->MediaChangeCount++;
2795 
2796  DebugPrint((2, "ScsiClassInterpretSenseInfo - Media change "
2797  "count for device %d is %d\n",
2798  physicalExtension->DeviceNumber,
2799  physicalExtension->MediaChangeCount));
2800 
2801  break;
2802 
2804 
2805  DebugPrint((1,"ScsiClassInterpretSenseInfo: Command aborted\n"));
2807  break;
2808 
2810 
2811  DebugPrint((1,"ScsiClassInterpretSenseInfo: Recovered error\n"));
2813  retry = FALSE;
2814  logError = TRUE;
2815  uniqueId = 258;
2816 
2817  switch(senseBuffer->AdditionalSenseCode) {
2820  logStatus = 0;//IO_ERR_SEEK_ERROR;
2821  break;
2822 
2825  logStatus = 0;//IO_RECOVERED_VIA_ECC;
2826  break;
2827 
2828  default:
2829  logStatus = 0;//IO_ERR_CONTROLLER_ERROR;
2830  break;
2831 
2832  } // end switch(senseBuffer->AdditionalSenseCode)
2833 
2834  if (senseBuffer->IncorrectLength) {
2835 
2836  DebugPrint((1, "ScsiClassInterpretSenseInfo: Incorrect length detected.\n"));
2838  }
2839 
2840  break;
2841 
2842  case SCSI_SENSE_NO_SENSE:
2843 
2844  //
2845  // Check other indicators.
2846  //
2847 
2848  if (senseBuffer->IncorrectLength) {
2849 
2850  DebugPrint((1, "ScsiClassInterpretSenseInfo: Incorrect length detected.\n"));
2852  retry = FALSE;
2853 
2854  } else {
2855 
2856  DebugPrint((1, "ScsiClassInterpretSenseInfo: No specific sense key\n"));
2858  retry = TRUE;
2859  }
2860 
2861  break;
2862 
2863  default:
2864 
2865  DebugPrint((1, "ScsiClassInterpretSenseInfo: Unrecognized sense code\n"));
2867  break;
2868 
2869  } // end switch (senseBuffer->SenseKey & 0xf)
2870 
2871  //
2872  // Try to determine the bad sector from the inquiry data.
2873  //
2874 
2875  if ((((PCDB)Srb->Cdb)->CDB10.OperationCode == SCSIOP_READ ||
2876  ((PCDB)Srb->Cdb)->CDB10.OperationCode == SCSIOP_VERIFY ||
2877  ((PCDB)Srb->Cdb)->CDB10.OperationCode == SCSIOP_WRITE)) {
2878 
2879  for (index = 0; index < 4; index++) {
2880  badSector = (badSector << 8) | senseBuffer->Information[index];
2881  }
2882 
2883  readSector = 0;
2884  for (index = 0; index < 4; index++) {
2885  readSector = (readSector << 8) | Srb->Cdb[index+2];
2886  }
2887 
2888  index = (((PCDB)Srb->Cdb)->CDB10.TransferBlocksMsb << 8) |
2889  ((PCDB)Srb->Cdb)->CDB10.TransferBlocksLsb;
2890 
2891  //
2892  // Make sure the bad sector is within the read sectors.
2893  //
2894 
2895  if (!(badSector >= readSector && badSector < readSector + index)) {
2896  badSector = readSector;
2897  }
2898  }
2899 
2900  } else {
2901 
2902  //
2903  // Request sense buffer not valid. No sense information
2904  // to pinpoint the error. Return general request fail.
2905  //
2906 
2907  DebugPrint((1,"ScsiClassInterpretSenseInfo: Request sense info not valid. SrbStatus %2x\n",
2908  SRB_STATUS(Srb->SrbStatus)));
2909  retry = TRUE;
2910 
2911  switch (SRB_STATUS(Srb->SrbStatus)) {
2914  case SRB_STATUS_NO_DEVICE:
2915  case SRB_STATUS_NO_HBA:
2918  retry = FALSE;
2919  break;
2920 
2922  case SRB_STATUS_ABORTED:
2923  case SRB_STATUS_TIMEOUT:
2924 
2925  //
2926  // Update the error count for the device.
2927  //
2928 
2929  deviceExtension->ErrorCount++;
2931  break;
2932 
2934  logError = TRUE;
2935  logStatus = 0;//IO_ERR_NOT_READY;
2936  uniqueId = 260;
2938  retry = FALSE;
2939  break;
2940 
2943  retry = FALSE;
2944  break;
2945 
2947 
2948  //
2949  // Update the error count for the device.
2950  //
2951 
2952  deviceExtension->ErrorCount++;
2954 
2955  //
2956  // If there was phase sequence error then limit the number of
2957  // retries.
2958  //
2959 
2960  if (RetryCount > 1 ) {
2961  retry = FALSE;
2962  }
2963 
2964  break;
2965 
2967 
2968  //
2969  // If the status needs verification bit is set. Then set
2970  // the status to need verification and no retry; otherwise,
2971  // just retry the request.
2972  //
2973 
2975 
2977  retry = FALSE;
2978  } else {
2980  }
2981 
2982  break;
2983 
2985 
2986  //
2987  // An invalid request was attempted.
2988  //
2989 
2991  retry = FALSE;
2992  break;
2993 
2996 
2997  //
2998  // Update the error count for the device.
2999  //
3000 
3001  deviceExtension->ErrorCount++;
3002 
3003  //
3004  // Fall through to below.
3005  //
3006 
3007  case SRB_STATUS_BUS_RESET:
3009  break;
3010 
3011  case SRB_STATUS_ERROR:
3012 
3014  if (Srb->ScsiStatus == 0) {
3015 
3016  //
3017  // This is some strange return code. Update the error
3018  // count for the device.
3019  //
3020 
3021  deviceExtension->ErrorCount++;
3022 
3023  } if (Srb->ScsiStatus == SCSISTAT_BUSY) {
3024 
3026 
3027  } if (Srb->ScsiStatus == SCSISTAT_RESERVATION_CONFLICT) {
3028 
3030  retry = FALSE;
3031 
3032  }
3033 
3034  break;
3035 
3036  default:
3037  logError = TRUE;
3038  logStatus = 0;//IO_ERR_CONTROLLER_ERROR;
3039  uniqueId = 259;
3041  break;
3042 
3043  }
3044 
3045  //
3046  // If the error count has exceeded the error limit, then disable
3047  // any tagged queuing, multiple requests per lu queueing
3048  // and synchronous data transfers.
3049  //
3050 
3051  if (deviceExtension->ErrorCount == 4) {
3052 
3053  //
3054  // Clearing the no queue freeze flag prevents the port driver
3055  // from sending multiple requests per logical unit.
3056  //
3057 
3058  deviceExtension->SrbFlags &= ~(SRB_FLAGS_QUEUE_ACTION_ENABLE |
3060 
3061  deviceExtension->SrbFlags |= SRB_FLAGS_DISABLE_SYNCH_TRANSFER;
3062  DebugPrint((1, "ScsiClassInterpretSenseInfo: Too many errors disabling tagged queuing and synchronous data tranfers.\n"));
3063 
3064  } else if (deviceExtension->ErrorCount == 8) {
3065 
3066  //
3067  // If a second threshold is reached, disable disconnects.
3068  //
3069 
3070  deviceExtension->SrbFlags |= SRB_FLAGS_DISABLE_DISCONNECT;
3071  DebugPrint((1, "ScsiClassInterpretSenseInfo: Too many errors disabling disconnects.\n"));
3072  }
3073  }
3074 
3075  //
3076  // If there is a class specific error handler call it.
3077  //
3078 
3079  if (deviceExtension->ClassError != NULL) {
3080 
3081  deviceExtension->ClassError(DeviceObject,
3082  Srb,
3083  Status,
3084  &retry);
3085  }
3086 
3087  //
3088  // Log an error if necessary.
3089  //
3090 
3091  if (logError) {
3092 
3094  DeviceObject,
3095  sizeof(IO_ERROR_LOG_PACKET) + 5 * sizeof(ULONG));
3096 
3097  if (errorLogEntry == NULL) {
3098 
3099  //
3100  // Return if no packet could be allocated.
3101  //
3102 
3103  return retry;
3104 
3105  }
3106 
3107  if (retry && RetryCount < MAXIMUM_RETRIES) {
3108  errorLogEntry->FinalStatus = STATUS_SUCCESS;
3109  } else {
3110  errorLogEntry->FinalStatus = *Status;
3111  }
3112 
3113  //
3114  // Calculate the device offset if there is a geometry.
3115  //
3116 
3117  if (deviceExtension->DiskGeometry != NULL) {
3118 
3119  errorLogEntry->DeviceOffset.QuadPart = (LONGLONG) badSector;
3120  errorLogEntry->DeviceOffset = RtlExtendedIntegerMultiply(
3121  errorLogEntry->DeviceOffset,
3122  deviceExtension->DiskGeometry->Geometry.BytesPerSector);
3123  }
3124 
3125  errorLogEntry->ErrorCode = logStatus;
3126  errorLogEntry->SequenceNumber = 0;
3127  errorLogEntry->MajorFunctionCode = MajorFunctionCode;
3128  errorLogEntry->IoControlCode = IoDeviceCode;
3129  errorLogEntry->RetryCount = (UCHAR) RetryCount;
3130  errorLogEntry->UniqueErrorValue = uniqueId;
3131  errorLogEntry->DumpDataSize = 6 * sizeof(ULONG);
3132  errorLogEntry->DumpData[0] = Srb->PathId;
3133  errorLogEntry->DumpData[1] = Srb->TargetId;
3134  errorLogEntry->DumpData[2] = Srb->Lun;
3135  errorLogEntry->DumpData[3] = 0;
3136  errorLogEntry->DumpData[4] = Srb->SrbStatus << 8 | Srb->ScsiStatus;
3137 
3138  if (senseBuffer != NULL) {
3139  errorLogEntry->DumpData[5] = senseBuffer->SenseKey << 16 |
3140  senseBuffer->AdditionalSenseCode << 8 |
3141  senseBuffer->AdditionalSenseCodeQualifier;
3142 
3143  }
3144 
3145  //
3146  // Write the error log packet.
3147  //
3148 
3149  IoWriteErrorLogEntry(errorLogEntry);
3150  }
3151 
3152  return retry;
3153 
3154 } // 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:454
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:1396
#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:2966
#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:65
#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 1806 of file class2.c.

1837 {
1840  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
1841  NTSTATUS status;
1842  BOOLEAN retry;
1843 
1844  ASSERT(*(PULONG)deviceExtension != '2slc');
1845 
1846  //
1847  // Check SRB status for success of completing request.
1848  //
1849 
1850  if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
1851 
1852  DebugPrint((2,"ScsiClassIoComplete: IRP %lx, SRB %lx\n", Irp, srb));
1853 
1854  //
1855  // Release the queue if it is frozen.
1856  //
1857 
1858  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
1860  }
1861 
1863  DeviceObject,
1864  srb,
1865  irpStack->MajorFunction,
1866  irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL ? irpStack->Parameters.DeviceIoControl.IoControlCode : 0,
1867  MAXIMUM_RETRIES - PtrToUlong(irpStack->Parameters.Others.Argument4),
1868  &status);
1869 
1870  //
1871  // If the status is verified required and the this request
1872  // should bypass verify required then retry the request.
1873  //
1874 
1875  if (irpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME &&
1877 
1879  retry = TRUE;
1880  }
1881 
1882  if (retry && (irpStack->Parameters.Others.Argument4 = (PVOID)((ULONG_PTR)irpStack->Parameters.Others.Argument4-1))) {
1883 
1884  //
1885  // Retry request.
1886  //
1887 
1888  DebugPrint((1, "Retry request %lx\n", Irp));
1891  }
1892  } else {
1893 
1894  //
1895  // Set status for successful request.
1896  //
1897 
1899 
1900  } // end if (SRB_STATUS(srb->SrbStatus) ...
1901 
1902  //
1903  // Return SRB to list.
1904  //
1905 
1906  ExFreeToNPagedLookasideList(&deviceExtension->SrbLookasideListHead,
1907  srb);
1908 
1909  //
1910  // Set status in completing IRP.
1911  //
1912 
1913  Irp->IoStatus.Status = status;
1914  if ((NT_SUCCESS(status)) && (Irp->Flags & IRP_PAGING_IO)) {
1915  ASSERT(Irp->IoStatus.Information);
1916  }
1917 
1918  //
1919  // Set the hard error if necessary.
1920  //
1921 
1923 
1924  //
1925  // Store DeviceObject for filesystem, and clear
1926  // in IoStatus.Information field.
1927  //
1928 
1930  Irp->IoStatus.Information = 0;
1931  }
1932 
1933  //
1934  // If pending has be returned for this irp then mark the current stack as
1935  // pending.
1936  //
1937 
1938  if (Irp->PendingReturned) {
1940  }
1941 
1942  if (deviceExtension->ClassStartIo) {
1943  if (irpStack->MajorFunction != IRP_MJ_DEVICE_CONTROL) {
1945  }
1946  }
1947 
1948  return status;
1949 
1950 } // end ScsiClassIoComplete()
#define TRUE
Definition: types.h:120
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
_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:3159
#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:1253
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:2462
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:1024
#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:2966
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 1955 of file class2.c.

1989 {
1992  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
1993  PIRP originalIrp = Irp->AssociatedIrp.MasterIrp;
1994  LONG irpCount;
1995  NTSTATUS status;
1996  BOOLEAN retry;
1997 
1998  ASSERT(*(PULONG)deviceExtension != '2slc');
1999 
2000  //
2001  // Check SRB status for success of completing request.
2002  //
2003 
2004  if (SRB_STATUS(srb->SrbStatus) != SRB_STATUS_SUCCESS) {
2005 
2006  DebugPrint((2,"ScsiClassIoCompleteAssociated: IRP %lx, SRB %lx", Irp, srb));
2007 
2008  //
2009  // Release the queue if it is frozen.
2010  //
2011 
2012  if (srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
2014  }
2015 
2017  DeviceObject,
2018  srb,
2019  irpStack->MajorFunction,
2020  irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL ? irpStack->Parameters.DeviceIoControl.IoControlCode : 0,
2021  MAXIMUM_RETRIES - PtrToUlong(irpStack->Parameters.Others.Argument4),
2022  &status);
2023 
2024  //
2025  // If the status is verified required and the this request
2026  // should bypass verify required then retry the request.
2027  //
2028 
2029  if (irpStack->Flags & SL_OVERRIDE_VERIFY_VOLUME &&
2031 
2033  retry = TRUE;
2034  }
2035 
2036  if (retry && (irpStack->Parameters.Others.Argument4 = (PVOID)((ULONG_PTR)irpStack->Parameters.Others.Argument4-1))) {
2037 
2038  //
2039  // Retry request. If the class driver has supplied a StartIo,
2040  // call it directly for retries.
2041  //
2042 
2043  DebugPrint((1, "Retry request %lx\n", Irp));
2044 
2045  /*
2046  if (!deviceExtension->ClassStartIo) {
2047  RetryRequest(DeviceObject, Irp, srb, TRUE);
2048  } else {
2049  deviceExtension->ClassStartIo(DeviceObject, Irp);
2050  }
2051  */
2052 
2054 
2056  }
2057 
2058 
2059 
2060  } else {
2061 
2062  //
2063  // Set status for successful request.
2064  //
2065 
2067 
2068  } // end if (SRB_STATUS(srb->SrbStatus) ...
2069 
2070  //
2071  // Return SRB to list.
2072  //
2073 
2074  ExFreeToNPagedLookasideList(&deviceExtension->SrbLookasideListHead,
2075  srb);
2076 
2077  //
2078  // Set status in completing IRP.
2079  //
2080 
2081  Irp->IoStatus.Status = status;
2082 
2083  DebugPrint((2, "ScsiClassIoCompleteAssociated: Partial xfer IRP %lx\n", Irp));
2084 
2085  //
2086  // Get next stack location. This original request is unused
2087  // except to keep track of the completing partial IRPs so the
2088  // stack location is valid.
2089  //
2090 
2091  irpStack = IoGetNextIrpStackLocation(originalIrp);
2092 
2093  //
2094  // Update status only if error so that if any partial transfer
2095  // completes with error, then the original IRP will return with
2096  // error. If any of the asynchronous partial transfer IRPs fail,
2097  // with an error then the original IRP will return 0 bytes transfered.
2098  // This is an optimization for successful transfers.
2099  //
2100 
2101  if (!NT_SUCCESS(status)) {
2102 
2103  originalIrp->IoStatus.Status = status;
2104  originalIrp->IoStatus.Information = 0;
2105 
2106  //
2107  // Set the hard error if necessary.
2108  //
2109 
2111 
2112  //
2113  // Store DeviceObject for filesystem.
2114  //
2115 
2117  }
2118  }
2119 
2120  //
2121  // Decrement and get the count of remaining IRPs.
2122  //
2123 
2124  irpCount = InterlockedDecrement((PLONG)&irpStack->Parameters.Others.Argument1);
2125 
2126  DebugPrint((2, "ScsiClassIoCompleteAssociated: Partial IRPs left %d\n",
2127  irpCount));
2128 
2129  //
2130  // Old bug could cause irp count to negative
2131  //
2132 
2133  ASSERT(irpCount >= 0);
2134 
2135  if (irpCount == 0) {
2136 
2137  //
2138  // All partial IRPs have completed.
2139  //
2140 
2141  DebugPrint((2,
2142  "ScsiClassIoCompleteAssociated: All partial IRPs complete %lx\n",
2143  originalIrp));
2144 
2145  IoCompleteRequest(originalIrp, IO_DISK_INCREMENT);
2146 
2147  //
2148  // If the class driver has supplied a startio, start the
2149  // next request.
2150  //
2151 
2152  if (deviceExtension->ClassStartIo) {
2154  }
2155  }
2156 
2157  //
2158  // Deallocate IRP and indicate the I/O system should not attempt any more
2159  // processing.
2160  //
2161 
2162  IoFreeIrp(Irp);
2164 
2165 } // end ScsiClassIoCompleteAssociated()
#define TRUE
Definition: types.h:120
#define STATUS_MORE_PROCESSING_REQUIRED
Definition: shellext.h:63
_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:3159
#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:1253
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:2462
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:1024
#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:2966
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 3513 of file class2.c.

3542 {
3543  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3544  PCDB cdb;
3545  SCSI_REQUEST_BLOCK srb;
3546  ULONG retries = 1;
3547  NTSTATUS status;
3548 
3549  ASSERT(*(PULONG)deviceExtension != '2slc');
3550 
3551  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
3552 
3553  //
3554  // Build the MODE SENSE CDB.
3555  //
3556 
3557  srb.CdbLength = 6;
3558  cdb = (PCDB)srb.Cdb;
3559 
3560  //
3561  // Set timeout value from device extension.
3562  //
3563 
3564  srb.TimeOutValue = deviceExtension->TimeOutValue;
3565 
3566  cdb->MODE_SENSE.OperationCode = SCSIOP_MODE_SENSE;
3567  cdb->MODE_SENSE.PageCode = PageMode;
3568  cdb->MODE_SENSE.AllocationLength = (UCHAR)Length;
3569 
3570 Retry:
3571 
3573  &srb,
3574  ModeSenseBuffer,
3575  Length,
3576  FALSE);
3577 
3578 
3579  if (status == STATUS_VERIFY_REQUIRED) {
3580 
3581  //
3582  // Routine ScsiClassSendSrbSynchronous does not retry requests returned with
3583  // this status. MODE SENSE commands should be retried anyway.
3584  //
3585 
3586  if (retries--) {
3587 
3588  //
3589  // Retry request.
3590  //
3591 
3592  goto Retry;
3593  }
3594 
3595  } else if (SRB_STATUS(srb.SrbStatus) == SRB_STATUS_DATA_OVERRUN) {
3597  }
3598 
3599  if (NT_SUCCESS(status)) {
3600  return(srb.DataTransferLength);
3601  } else {
3602  return(0);
3603  }
3604 
3605 } // 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:2966
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:2170
Definition: ps.c:97

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

◆ ScsiClassReadDriveCapacity()

NTSTATUS ScsiClassReadDriveCapacity ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 1029 of file class2.c.

1051 {
1052  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
1053  ULONG retries = 1;
1054  ULONG lastSector;
1055  PCDB cdb;
1056  PREAD_CAPACITY_DATA readCapacityBuffer;
1057  SCSI_REQUEST_BLOCK srb;
1058  NTSTATUS status;
1059 
1060  ASSERT(*(PULONG)deviceExtension != '2slc');
1061 
1062  //
1063  // Allocate read capacity buffer from nonpaged pool.
1064  //
1065 
1066  readCapacityBuffer = ExAllocatePool(NonPagedPoolCacheAligned,
1067  sizeof(READ_CAPACITY_DATA));
1068 
1069  if (!readCapacityBuffer) {
1071  }
1072 
1073  RtlZeroMemory(&srb, sizeof(SCSI_REQUEST_BLOCK));
1074 
1075  //
1076  // Build the read capacity CDB.
1077  //
1078 
1079  srb.CdbLength = 10;
1080  cdb = (PCDB)srb.Cdb;
1081 
1082  //
1083  // Set timeout value from device extension.
1084  //
1085 
1086  srb.TimeOutValue = deviceExtension->TimeOutValue;
1087 
1088  cdb->CDB10.OperationCode = SCSIOP_READ_CAPACITY;
1089 
1090 Retry:
1091 
1093  &srb,
1094  readCapacityBuffer,
1095  sizeof(READ_CAPACITY_DATA),
1096  FALSE);
1097 
1098  if (NT_SUCCESS(status)) {
1099 
1100  //
1101  // Copy sector size from read capacity buffer to device extension
1102  // in reverse byte order.
1103  //
1104 
1105  ((PFOUR_BYTE)&deviceExtension->DiskGeometry->Geometry.BytesPerSector)->Byte0 =
1106  ((PFOUR_BYTE)&readCapacityBuffer->BytesPerBlock)->Byte3;
1107 
1108  ((PFOUR_BYTE)&deviceExtension->DiskGeometry->Geometry.BytesPerSector)->Byte1 =
1109  ((PFOUR_BYTE)&readCapacityBuffer->BytesPerBlock)->Byte2;
1110 
1111  ((PFOUR_BYTE)&deviceExtension->DiskGeometry->Geometry.BytesPerSector)->Byte2 =
1112  ((PFOUR_BYTE)&readCapacityBuffer->BytesPerBlock)->Byte1;
1113 
1114  ((PFOUR_BYTE)&deviceExtension->DiskGeometry->Geometry.BytesPerSector)->Byte3 =
1115  ((PFOUR_BYTE)&readCapacityBuffer->BytesPerBlock)->Byte0;
1116 
1117  //
1118  // Copy last sector in reverse byte order.
1119  //
1120 
1121  ((PFOUR_BYTE)&lastSector)->Byte0 =
1122  ((PFOUR_BYTE)&readCapacityBuffer->LogicalBlockAddress)->Byte3;
1123 
1124  ((PFOUR_BYTE)&lastSector)->Byte1 =
1125  ((PFOUR_BYTE)&readCapacityBuffer->LogicalBlockAddress)->Byte2;
1126 
1127  ((PFOUR_BYTE)&lastSector)->Byte2 =
1128  ((PFOUR_BYTE)&readCapacityBuffer->LogicalBlockAddress)->Byte1;
1129 
1130  ((PFOUR_BYTE)&lastSector)->Byte3 =
1131  ((PFOUR_BYTE)&readCapacityBuffer->LogicalBlockAddress)->Byte0;
1132 
1133  //
1134  // Calculate sector to byte shift.
1135  //
1136 
1137  WHICH_BIT(deviceExtension->DiskGeometry->Geometry.BytesPerSector, deviceExtension->SectorShift);
1138 
1139  DebugPrint((2,"SCSI ScsiClassReadDriveCapacity: Sector size is %d\n",
1140  deviceExtension->DiskGeometry->Geometry.BytesPerSector));
1141 
1142  DebugPrint((2,"SCSI ScsiClassReadDriveCapacity: Number of Sectors is %d\n",
1143  lastSector + 1));
1144 
1145  //
1146  // Calculate media capacity in bytes.
1147  //
1148 
1149  deviceExtension->PartitionLength.QuadPart = (LONGLONG)(lastSector + 1);
1150 
1151  //
1152  // Calculate number of cylinders.
1153  //
1154 
1155  deviceExtension->DiskGeometry->Geometry.Cylinders.QuadPart = (LONGLONG)((lastSector + 1)/(DEFAULT_SECTORS_PER_TRACK * DEFAULT_TRACKS_PER_CYLINDER));
1156 
1157  deviceExtension->PartitionLength.QuadPart =
1158  (deviceExtension->PartitionLength.QuadPart << deviceExtension->SectorShift);
1159 
1160  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
1161 
1162  //
1163  // This device supports removable media.
1164  //
1165 
1166  deviceExtension->DiskGeometry->Geometry.MediaType = RemovableMedia;
1167 
1168  } else {
1169 
1170  //
1171  // Assume media type is fixed disk.
1172  //
1173 
1174  deviceExtension->DiskGeometry->Geometry.MediaType = FixedMedia;
1175  }
1176 
1177  //
1178  // Assume sectors per track are DEFAULT_SECTORS_PER_TRACK;
1179  //
1180 
1181  deviceExtension->DiskGeometry->Geometry.SectorsPerTrack = DEFAULT_SECTORS_PER_TRACK;
1182 
1183  //
1184  // Assume tracks per cylinder (number of heads) is DEFAULT_TRACKS_PER_CYLINDER.
1185  //
1186 
1187  deviceExtension->DiskGeometry->Geometry.TracksPerCylinder = DEFAULT_TRACKS_PER_CYLINDER;
1188  }
1189 
1190  if (status == STATUS_VERIFY_REQUIRED) {
1191 
1192  //
1193  // Routine ScsiClassSendSrbSynchronous does not retry
1194  // requests returned with this status.
1195  // Read Capacities should be retried
1196  // anyway.
1197  //
1198 
1199  if (retries--) {
1200 
1201  //
1202  // Retry request.
1203  //
1204 
1205  goto Retry;
1206  }
1207  }
1208 
1209  if (!NT_SUCCESS(status)) {
1210 
1211  //
1212  // If the read capacity fails, set the geometry to reasonable parameter
1213  // so things don't fail at unexpected places. Zero the geometry
1214  // except for the bytes per sector and sector shift.
1215  //
1216 
1217  RtlZeroMemory(deviceExtension->DiskGeometry, sizeof(DISK_GEOMETRY_EX));
1218  deviceExtension->DiskGeometry->Geometry.BytesPerSector = 512;
1219  deviceExtension->SectorShift = 9;
1220  deviceExtension->PartitionLength.QuadPart = (LONGLONG) 0;
1221 
1222  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
1223 
1224  //
1225  // This device supports removable media.
1226  //
1227 
1228  deviceExtension->DiskGeometry->Geometry.MediaType = RemovableMedia;
1229 
1230  } else {
1231 
1232  //
1233  // Assume media type is fixed disk.
1234  //
1235 
1236  deviceExtension->DiskGeometry->Geometry.MediaType = FixedMedia;
1237  }
1238  }
1239 
1240  //
1241  // Deallocate read capacity buffer.
1242  //
1243 
1244  ExFreePool(readCapacityBuffer);
1245 
1246  return status;
1247 
1248 } // 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:41
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:2170
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define DEFAULT_TRACKS_PER_CYLINDER
Definition: class2.c:42
Definition: ps.c:97

◆ ScsiClassReleaseQueue()

VOID ScsiClassReleaseQueue ( IN PDEVICE_OBJECT  DeviceObject)

Definition at line 1253 of file class2.c.

1277 {
1278  PIO_STACK_LOCATION irpStack;
1279  PIRP irp;
1280  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
1282  PSCSI_REQUEST_BLOCK srb;
1283  KIRQL currentIrql;
1284 
1285  ASSERT(*(PULONG)deviceExtension != '2slc');
1286 
1287  //
1288  // Allocate context from nonpaged pool.
1289  //
1290 
1292  sizeof(COMPLETION_CONTEXT));
1293 
1294  //
1295  // Save the device object in the context for use by the completion
1296  // routine.
1297  //
1298 
1299  context->DeviceObject = DeviceObject;
1300  srb = &context->Srb;
1301 
1302  //
1303  // Zero out srb.
1304  //
1305 
1307 
1308  //
1309  // Write length to SRB.
1310  //
1311 
1313 
1314  //
1315  // Set up SCSI bus address.
1316  //
1317 
1318  srb->PathId = deviceExtension->PathId;
1319  srb->TargetId = deviceExtension->TargetId;
1320  srb->Lun = deviceExtension->Lun;
1321 
1322  //
1323  // If this device is removable then flush the queue. This will also
1324  // release it.
1325  //
1326 
1327  if (DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA) {
1328 
1330 
1331  } else {
1332 
1334 
1335  }
1336 
1337  //
1338  // Build the asynchronous request to be sent to the port driver.
1339  //
1340 
1342 
1343  if(irp == NULL) {
1344 
1345  //
1346  // We have no better way of dealing with this at the moment
1347  //
1348 
1349  KeBugCheck((ULONG)0x0000002DL);
1350 
1351  }
1352 
1355  context,
1356  TRUE,
1357  TRUE,
1358  TRUE);
1359 
1360  irpStack = IoGetNextIrpStackLocation(irp);
1361 
1362  irpStack->MajorFunction = IRP_MJ_SCSI;
1363 
1364  srb->OriginalRequest = irp;
1365 
1366  //
1367  // Store the SRB address in next stack for port driver.
1368  //
1369 
1370  irpStack->Parameters.Scsi.Srb = srb;
1371 
1372  //
1373  // Since this routine can cause outstanding requests to be completed, and
1374  // calling a completion routine at < DISPATCH_LEVEL is dangerous (if they
1375  // call IoStartNextPacket we will bugcheck) raise up to dispatch level before
1376  // issuing the request
1377  //
1378 
1379  currentIrql = KeGetCurrentIrql();
1380 
1381  if(currentIrql < DISPATCH_LEVEL) {
1382  KeRaiseIrql(DISPATCH_LEVEL, &currentIrql);
1383  IoCallDriver(deviceExtension->PortDeviceObject, irp);
1384  KeLowerIrql(currentIrql);
1385  } else {
1386  IoCallDriver(deviceExtension->PortDeviceObject, irp);
1387  }
1388 
1389  return;
1390 
1391 } // 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:6587
NTSTATUS NTAPI ScsiClassAsynchronousCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
Definition: class2.c:1531
#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 3684 of file class2.c.

3720 {
3721 
3722  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
3723  PIO_STACK_LOCATION irpStack;
3724 
3725  PAGED_CODE();
3726 
3727  ASSERT(*(PULONG)deviceExtension != '2slc');
3728 
3729  //
3730  // Write length to SRB.
3731  //
3732 
3733  Srb->Length = SCSI_REQUEST_BLOCK_SIZE;
3734 
3735  //
3736  // Set SCSI bus address.
3737  //
3738 
3739  Srb->PathId = deviceExtension->PathId;
3740  Srb->TargetId = deviceExtension->TargetId;
3741  Srb->Lun = deviceExtension->Lun;
3742 
3743  Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
3744 
3745  //
3746  // This is a violation of the SCSI spec but it is required for
3747  // some targets.
3748  //
3749 
3750  Srb->Cdb[1] |= deviceExtension->Lun << 5;
3751 
3752  //
3753  // Indicate auto request sense by specifying buffer and size.
3754  //
3755 
3756  Srb->SenseInfoBuffer = deviceExtension->SenseData;
3757  Srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
3758  Srb->DataBuffer = BufferAddress;
3759 
3760  if (BufferAddress != NULL) {
3761 
3762  //
3763  // Build Mdl if necessary.
3764  //
3765 
3766  if (Irp->MdlAddress == NULL) {
3767 
3768  if (IoAllocateMdl(BufferAddress,
3769  BufferLength,
3770  FALSE,
3771  FALSE,
3772  Irp) == NULL) {
3773 
3775  }
3776 
3777  MmBuildMdlForNonPagedPool(Irp->MdlAddress);
3778 
3779  } else {
3780 
3781  //
3782  // Make sure the buffer requested matches the MDL.
3783  //
3784 
3785  ASSERT(BufferAddress == MmGetMdlVirtualAddress(Irp->MdlAddress));
3786  }
3787 
3788  //
3789  // Set read flag.
3790  //
3791 
3792  Srb->SrbFlags = WriteToDevice ? SRB_FLAGS_DATA_OUT : SRB_FLAGS_DATA_IN;
3793 
3794  } else {
3795 
3796  //
3797  // Clear flags.
3798  //
3799 
3800  Srb->SrbFlags = SRB_FLAGS_NO_DATA_TRANSFER;
3801  }
3802 
3803  //
3804  // Disable synchronous transfer for these requests.
3805  //
3806 
3808 
3809  //
3810  // Set the transfer length.
3811  //
3812 
3813  Srb->DataTransferLength = BufferLength;
3814 
3815  //
3816  // Zero out status.
3817  //
3818 
3819  Srb->ScsiStatus = Srb->SrbStatus = 0;
3820 
3821  Srb->NextSrb = 0;
3822 
3823  //
3824  // Save a few parameters in the current stack location.
3825  //
3826 
3827  irpStack = IoGetCurrentIrpStackLocation(Irp);
3828 
3829  //
3830  // Save retry count in current Irp stack.
3831  //
3832 
3833  irpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
3834 
3835  //
3836  // Set up IoCompletion routine address.
3837  //
3838 
3840 
3841  //
3842  // Get next stack location and
3843  // set major function code.
3844  //
3845 
3846  irpStack = IoGetNextIrpStackLocation(Irp);
3847 
3848  irpStack->MajorFunction = IRP_MJ_SCSI;
3849 
3850  //
3851  // Save SRB address in next stack for port driver.
3852  //
3853 
3854  irpStack->Parameters.Scsi.Srb = Srb;
3855 
3856  //
3857  // Set up Irp Address.
3858  //
3859 
3860  Srb->OriginalRequest = Irp;
3861 
3862  //
3863  // Call the port driver to process the request.
3864  //
3865 
3866  return(IoCallDriver(deviceExtension->PortDeviceObject, Irp));
3867 
3868 }
#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:1806
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 2170 of file class2.c.

2206 {
2207  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
2208  IO_STATUS_BLOCK ioStatus;
2209  ULONG controlType, mjFunction;
2210  PIRP irp;
2211  PIO_STACK_LOCATION irpStack;
2212  KEVENT event;
2213  PUCHAR senseInfoBuffer;
2214  ULONG retryCount = MAXIMUM_RETRIES;
2215  NTSTATUS status;
2216  BOOLEAN retry;
2218 
2219  PAGED_CODE();
2220 
2221  ASSERT(*(PULONG)deviceExtension != '2slc');
2222 
2223  dummy.QuadPart = 0;
2224 
2225  //
2226  // Write length to SRB.
2227  //
2228 
2229  Srb->Length = SCSI_REQUEST_BLOCK_SIZE;
2230 
2231  //
2232  // Set SCSI bus address.
2233  //
2234 
2235  Srb->PathId = deviceExtension->PathId;
2236  Srb->TargetId = deviceExtension->TargetId;
2237  Srb->Lun = deviceExtension->Lun;
2238  Srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
2239 
2240  //
2241  // NOTICE: The SCSI-II specification indicates that this field should be
2242  // zero; however, some target controllers ignore the logical unit number
2243  // in the IDENTIFY message and only look at the logical unit number field
2244  // in the CDB.
2245  //
2246 
2247  Srb->Cdb[1] |= deviceExtension->Lun << 5;
2248 
2249  //
2250  // Enable auto request sense.
2251  //
2252 
2253  Srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
2254 
2255  //
2256  // Sense buffer is in aligned nonpaged pool.
2257  //
2258 
2260 
2261  if (senseInfoBuffer == NULL) {
2262 
2263  DebugPrint((1,
2264  "ScsiClassSendSrbSynchronous: Can't allocate request sense buffer\n"));
2266  }
2267 
2268  Srb->SenseInfoBuffer = senseInfoBuffer;
2269  Srb->DataBuffer = BufferAddress;
2270 
2271  //
2272  // Start retries here.
2273  //
2274 
2275 retry:
2276 
2277  //
2278  // Set the event object to the unsignaled state.
2279  // It will be used to signal request completion.
2280  //
2281 
2283 
2284  //
2285  // Set controlType and Srb direction flags.
2286  //
2287 
2288  if (BufferAddress != NULL) {
2289 
2290  if (WriteToDevice) {
2291 
2292  controlType = IOCTL_SCSI_EXECUTE_OUT;
2293  Srb->SrbFlags = SRB_FLAGS_DATA_OUT;
2294  mjFunction = IRP_MJ_WRITE;
2295 
2296  } else {
2297 
2298  controlType = IOCTL_SCSI_EXECUTE_IN;
2299  Srb->SrbFlags = SRB_FLAGS_DATA_IN;
2300  mjFunction = IRP_MJ_READ;
2301  }
2302 
2303  } else {
2304 
2305  BufferLength = 0;
2306  controlType = IOCTL_SCSI_EXECUTE_NONE;
2307  Srb->SrbFlags = SRB_FLAGS_NO_DATA_TRANSFER;
2308  mjFunction = IRP_MJ_FLUSH_BUFFERS;
2309  }
2310 
2311  //
2312  // Build device I/O control request with data transfer.
2313  //
2315  mjFunction,
2316  deviceExtension->DeviceObject,
2317  BufferAddress,
2318  (BufferAddress) ? BufferLength : 0,
2319  &dummy,
2320  &ioStatus);
2321 
2322  if (irp == NULL) {
2323  ExFreePool(senseInfoBuffer);
2324  DebugPrint((1, "ScsiClassSendSrbSynchronous: Can't allocate Irp\n"));
2326  }
2327 
2328  // Set event field
2329  irp->UserEvent = &event;
2330 
2331  //
2332  // Disable synchronous transfer for these requests.
2333  //
2334 
2336 
2337  //
2338  // Set the transfer length.
2339  //
2340 
2341  Srb->DataTransferLength = BufferLength;
2342 
2343  //
2344  // Zero out status.
2345  //
2346 
2347  Srb->ScsiStatus = Srb->SrbStatus = 0;
2348  Srb->NextSrb = 0;
2349 
2350  // Set completion routine
2352  irp,
2354  NULL,
2355  TRUE,
2356  TRUE,
2357  TRUE);
2358 
2359  //
2360  // Get next stack location.
2361  //
2362 
2363  irpStack = IoGetNextIrpStackLocation(irp);
2364 
2366  irpStack->Parameters.DeviceIoControl.IoControlCode = controlType;
2367 
2368  //
2369  // Set up SRB for execute scsi request. Save SRB address in next stack
2370  // for the port driver.
2371  //
2372 
2373  irpStack->Parameters.Scsi.Srb = Srb;
2374 
2375  //
2376  // Set up IRP Address.
2377  //
2378 
2379  Srb->OriginalRequest = irp;
2380 
2381  //
2382  // Call the port driver with the request and wait for it to complete.
2383  //
2384 
2385  status = IoCallDriver(deviceExtension->PortDeviceObject, irp);
2386 
2387  if (status == STATUS_PENDING) {
2389  }
2390 
2391  //
2392  // Check that request completed without error.
2393  //
2394 
2395  if (SRB_STATUS(Srb->SrbStatus) != SRB_STATUS_SUCCESS) {
2396 
2397  //
2398  // Release the queue if it is frozen.
2399  //
2400 
2401  if (Srb->SrbStatus & SRB_STATUS_QUEUE_FROZEN) {
2403  }
2404 
2405  //
2406  // Update status and determine if request should be retried.
2407  //
2408 
2410  Srb,
2411  IRP_MJ_SCSI,
2412  0,
2413  MAXIMUM_RETRIES - retryCount,
2414  &status);
2415 
2416  if (retry) {
2417 
2418  if ((status == STATUS_DEVICE_NOT_READY && ((PSENSE_DATA) senseInfoBuffer)
2419  ->AdditionalSenseCode == SCSI_ADSENSE_LUN_NOT_READY) ||
2420  SRB_STATUS(Srb->SrbStatus) == SRB_STATUS_SELECTION_TIMEOUT) {
2421 
2423 
2424  //
2425  // Delay for 2 seconds.
2426  //
2427 
2428  delay.QuadPart = (LONGLONG)( - 10 * 1000 * 1000 * 2 );
2429 
2430  //
2431  // Stall for a while to let the controller spinup.
2432  //
2433 
2435  FALSE,
2436  &delay);
2437 
2438  }
2439 
2440  //
2441  // If retries are not exhausted then retry this operation.
2442  //
2443 
2444  if (retryCount--) {
2445  goto retry;
2446  }
2447  }
2448 
2449  } else {
2450 
2452  }
2453 
2454  ExFreePool(senseInfoBuffer);
2455  return status;
2456 
2457 } // 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:1253
_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:5226
#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:2462
#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:2966
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:65
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 1612 of file class2.c.

1643 {
1644  PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
1647  ULONG transferByteCount = currentIrpStack->Parameters.Read.Length;
1648  LARGE_INTEGER startingOffset = currentIrpStack->Parameters.Read.ByteOffset;
1649  PVOID dataBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
1650  ULONG dataLength = MaximumBytes;
1651  ULONG irpCount = (transferByteCount + MaximumBytes - 1) / MaximumBytes;
1652  ULONG i;
1653  PSCSI_REQUEST_BLOCK srb;
1654 
1655  DebugPrint((2, "ScsiClassSplitRequest: Requires %d IRPs\n", irpCount));
1656  DebugPrint((2, "ScsiClassSplitRequest: Original IRP %lx\n", Irp));
1657 
1658  ASSERT(*(PULONG)deviceExtension != '2slc');
1659 
1660  //
1661  // If all partial transfers complete successfully then the status and
1662  // bytes transferred are already set up. Failing a partial-transfer IRP
1663  // will set status to error and bytes transferred to 0 during
1664  // IoCompletion. Setting bytes transferred to 0 if an IRP fails allows
1665  // asynchronous partial transfers. This is an optimization for the
1666  // successful case.
1667  //
1668 
1669  Irp->IoStatus.Status = STATUS_SUCCESS;
1670  Irp->IoStatus.Information = transferByteCount;
1671 
1672  //
1673  // Save number of IRPs to complete count on current stack
1674  // of original IRP.
1675  //
1676 
1677  nextIrpStack->Parameters.Others.Argument1 = (PVOID)(ULONG_PTR) irpCount;
1678 
1679  for (i = 0; i < irpCount; i++) {
1680 
1681  PIRP newIrp;
1682  PIO_STACK_LOCATION newIrpStack;
1683 
1684  //
1685  // Allocate new IRP.
1686  //
1687 
1689 
1690  if (newIrp == NULL) {
1691 
1692  DebugPrint((1,"ScsiClassSplitRequest: Can't allocate Irp\n"));
1693 
1694  //
1695  // If an Irp can't be allocated then the original request cannot
1696  // be executed. If this is the first request then just fail the
1697  // original request; otherwise just return. When the pending
1698  // requests complete, they will complete the original request.
1699  // In either case set the IRP status to failure.
1700  //
1701 
1702  Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
1703  Irp->IoStatus.Information = 0;
1704 
1705  if (i == 0) {
1707  }
1708 
1709  return;
1710  }
1711 
1712  DebugPrint((2, "ScsiClassSplitRequest: New IRP %lx\n", newIrp));
1713 
1714  //
1715  // Write MDL address to new IRP. In the port driver the SRB data
1716  // buffer field is used as an offset into the MDL, so the same MDL
1717  // can be used for each partial transfer. This saves having to build
1718  // a new MDL for each partial transfer.
1719  //
1720 
1721  newIrp->MdlAddress = Irp->MdlAddress;
1722 
1723  //
1724  // At this point there is no current stack. IoSetNextIrpStackLocation
1725  // will make the first stack location the current stack so that the
1726  // SRB address can be written there.
1727  //
1728 
1729  IoSetNextIrpStackLocation(newIrp);
1730  newIrpStack = IoGetCurrentIrpStackLocation(newIrp);
1731 
1732  newIrpStack->MajorFunction = currentIrpStack->MajorFunction;
1733  newIrpStack->Parameters.Read.Length = dataLength;
1734  newIrpStack->Parameters.Read.ByteOffset = startingOffset;
1735  newIrpStack->DeviceObject = DeviceObject;
1736 
1737  //
1738  // Build SRB and CDB.
1739  //
1740 
1742 
1743  //
1744  // Adjust SRB for this partial transfer.
1745  //
1746 
1747  newIrpStack = IoGetNextIrpStackLocation(newIrp);
1748 
1749  srb = newIrpStack->Parameters.Others.Argument1;
1750  srb->DataBuffer = dataBuffer;
1751 
1752  //
1753  // Write original IRP address to new IRP.
1754  //
1755 
1756  newIrp->AssociatedIrp.MasterIrp = Irp;
1757 
1758  //
1759  // Set the completion routine to ScsiClassIoCompleteAssociated.
1760  //
1761 
1762  IoSetCompletionRoutine(newIrp,
1764  srb,
1765  TRUE,
1766  TRUE,
1767  TRUE);
1768 
1769  //
1770  // Call port driver with new request.
1771  //
1772 
1773  IoCallDriver(deviceExtension->PortDeviceObject, newIrp);
1774 
1775  //
1776  // Set up for next request.
1777  //
1778 
1779  dataBuffer = (PCHAR)dataBuffer + MaximumBytes;
1780 
1781  transferByteCount -= MaximumBytes;
1782 
1783  if (transferByteCount > MaximumBytes) {
1784 
1785  dataLength = MaximumBytes;
1786 
1787  } else {
1788 
1789  dataLength = transferByteCount;
1790  }
1791 
1792  //
1793  // Adjust disk byte offset.
1794  //
1795 
1796  startingOffset.QuadPart = startingOffset.QuadPart + MaximumBytes;
1797  }
1798 
1799  return;
1800 
1801 } // end ScsiClassSplitRequest()
NTSTATUS NTAPI ScsiClassIoCompleteAssociated(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context)
Definition: class2.c:1955
#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:3284
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:2966
FORCEINLINE VOID IoSetNextIrpStackLocation(_Inout_ PIRP Irp)
Definition: iofuncs.h:2632
LONGLONG QuadPart
Definition: typedefs.h:112

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