{
PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension;
PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp);
LARGE_INTEGER startingOffset = currentIrpStack->Parameters.Read.ByteOffset;
PSCSI_REQUEST_BLOCK srb;
PCDB cdb;
ULONG logicalBlockAddress;
USHORT transferBlocks;
//// Calculate relative sector address.//
logicalBlockAddress = (ULONG)(Int64ShrlMod32(startingOffset.QuadPart, deviceExtension->SectorShift));
//// Allocate an Srb.//
srb = ExAllocateFromNPagedLookasideList(&deviceExtension->SrbLookasideListHead);
srb->SrbFlags = 0;
//// Write length to SRB.//
srb->Length = SCSI_REQUEST_BLOCK_SIZE;
//// Set up IRP Address.//
srb->OriginalRequest = Irp;
//// Set up target ID and logical unit number.//
srb->PathId = deviceExtension->PathId;
srb->TargetId = deviceExtension->TargetId;
srb->Lun = deviceExtension->Lun;
srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
srb->DataBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
//// Save byte count of transfer in SRB Extension.//
srb->DataTransferLength = currentIrpStack->Parameters.Read.Length;
//// Initialize the queue actions field.//
srb->QueueAction = SRB_SIMPLE_TAG_REQUEST;
//// Queue sort key is Relative Block Address.//
srb->QueueSortKey = logicalBlockAddress;
//// Indicate auto request sense by specifying buffer and size.//
srb->SenseInfoBuffer = deviceExtension->SenseData;
srb->SenseInfoBufferLength = SENSE_BUFFER_SIZE;
//// Set timeout value of one unit per 64k bytes of data.//
srb->TimeOutValue = ((srb->DataTransferLength + 0xFFFF) >> 16) *
deviceExtension->TimeOutValue;
//// Zero statuses.//
srb->SrbStatus = srb->ScsiStatus = 0;
srb->NextSrb = 0;
//// Indicate that 10-byte CDB's will be used.//
srb->CdbLength = 10;
//// Fill in CDB fields.//
cdb = (PCDB)srb->Cdb;
//// Zero 12 bytes for Atapi Packets//RtlZeroMemory(cdb, MAXIMUM_CDB_SIZE);
cdb->CDB10.LogicalUnitNumber = deviceExtension->Lun;
transferBlocks = (USHORT)(currentIrpStack->Parameters.Read.Length >> deviceExtension->SectorShift);
//// Move little endian values into CDB in big endian format.//
cdb->CDB10.LogicalBlockByte0 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte3;
cdb->CDB10.LogicalBlockByte1 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte2;
cdb->CDB10.LogicalBlockByte2 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte1;
cdb->CDB10.LogicalBlockByte3 = ((PFOUR_BYTE)&logicalBlockAddress)->Byte0;
cdb->CDB10.TransferBlocksMsb = ((PFOUR_BYTE)&transferBlocks)->Byte1;
cdb->CDB10.TransferBlocksLsb = ((PFOUR_BYTE)&transferBlocks)->Byte0;
//// Set transfer direction flag and Cdb command.//if (currentIrpStack->MajorFunction == IRP_MJ_READ) {
DebugPrint((3, "ScsiClassBuildRequest: Read Command\n"));
srb->SrbFlags |= SRB_FLAGS_DATA_IN;
cdb->CDB10.OperationCode = SCSIOP_READ;
} else {
DebugPrint((3, "ScsiClassBuildRequest: Write Command\n"));
srb->SrbFlags |= SRB_FLAGS_DATA_OUT;
cdb->CDB10.OperationCode = SCSIOP_WRITE;
}
//// If this is not a write-through request, then allow caching.//if (!(currentIrpStack->Flags & SL_WRITE_THROUGH)) {
srb->SrbFlags |= SRB_FLAGS_ADAPTER_CACHE_ENABLE;
} else {
//// If write caching is enable then force media access in the// cdb.//if (deviceExtension->DeviceFlags & DEV_WRITE_CACHE) {
cdb->CDB10.ForceUnitAccess = TRUE;
}
}
//// Or in the default flags from the device object.//
srb->SrbFlags |= deviceExtension->SrbFlags;
//// Set up major SCSI function.//
nextIrpStack->MajorFunction = IRP_MJ_SCSI;
//// Save SRB address in next stack for port driver.//
nextIrpStack->Parameters.Scsi.Srb = srb;
//// Save retry count in current IRP stack.//
currentIrpStack->Parameters.Others.Argument4 = (PVOID)MAXIMUM_RETRIES;
//// Set up IoCompletion routine address.//IoSetCompletionRoutine(Irp, ScsiClassIoComplete, srb, TRUE, TRUE, TRUE);
return;
} // end ScsiClassBuildRequest()
Generated on Fri May 25 2012 05:23:31 for ReactOS by
1.7.6.1
ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.