IOSCSIBlockCommandsBuilder.cpp   [plain text]


/*
 * Copyright (c) 1998-2002 Apple Computer, Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this
 * file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	Includes
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

// SCSI Architecture Model Family includes
#include <IOKit/scsi/SCSICommandDefinitions.h>
#include "IOSCSIBlockCommandsDevice.h"
#include "SCSIBlockCommands.h"
#include "SCSICommandOperationCodes.h"

//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	Macros
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

#define DEBUG 									0
#define DEBUG_ASSERT_COMPONENT_NAME_STRING		"SBC"

#if DEBUG
#define SCSI_SBC_DEVICE_DEBUGGING_LEVEL			0
#endif


#include "IOSCSIArchitectureModelFamilyDebugging.h"


#if 0
#pragma mark -
#pragma markBlock Commands Builders
#pragma mark -
#endif


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ ERASE_10 - 	Builds a ERASE_10 command.						[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::ERASE_10 (
						SCSITaskIdentifier			request,
						SCSICmdField1Bit 			ERA, 
						SCSICmdField1Bit 			RELADR, 
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS, 
						SCSICmdField2Byte 			TRANSFER_LENGTH, 
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->ERASE_10 (
					scsiRequest,
					ERA, 
					RELADR, 
					LOGICAL_BLOCK_ADDRESS, 
					TRANSFER_LENGTH, 
					CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ ERASE_12 - Builds a ERASE_12 command.							[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::ERASE_12 (
						SCSITaskIdentifier			request,
						SCSICmdField1Bit 			ERA, 
						SCSICmdField1Bit 			RELADR, 
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS, 
						SCSICmdField4Byte 			TRANSFER_LENGTH, 
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->ERASE_12 (
				scsiRequest,
				ERA, 
				RELADR, 
				LOGICAL_BLOCK_ADDRESS, 
				TRANSFER_LENGTH, 
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ FORMAT_UNIT - Builds a FORMAT_UNIT command.					[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::FORMAT_UNIT(
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						IOByteCount					defectListSize,
						SCSICmdField1Bit 			FMTDATA, 
						SCSICmdField1Bit 			CMPLST, 
						SCSICmdField3Bit 			DEFECT_LIST_FORMAT, 
						SCSICmdField1Byte 			VENDOR_SPECIFIC, 
						SCSICmdField2Byte 			INTERLEAVE, 
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );

	status = GetSCSIBlockCommandObject ( )->FORMAT_UNIT (
				scsiRequest,
				dataBuffer,
				defectListSize,
				FMTDATA, 
				CMPLST, 
				DEFECT_LIST_FORMAT, 
				VENDOR_SPECIFIC, 
				INTERLEAVE, 
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ FORMAT_UNIT - Builds a FORMAT_UNIT command.					[PROTECTED]
//  Defined in SBC-2 Section 5.41
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::FORMAT_UNIT (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						IOByteCount					defectListSize,
						SCSICmdField1Bit			FMTPINFO,
						SCSICmdField1Bit			RTO_REQ,
						SCSICmdField1Bit			LONGLIST,
						SCSICmdField1Bit 			FMTDATA, 
						SCSICmdField1Bit 			CMPLST,
						SCSICmdField3Bit 			DEFECT_LIST_FORMAT, 
						SCSICmdField1Byte 			VENDOR_SPECIFIC, 
						SCSICmdField1Byte 			CONTROL )
{

	bool		status 		= false;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );
	
	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( FMTPINFO, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( RTO_REQ, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LONGLIST, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( FMTDATA, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( CMPLST, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( DEFECT_LIST_FORMAT, kSCSICmdFieldMask3Bit ), ErrorExit );
	require ( IsParameterValid ( VENDOR_SPECIFIC, kSCSICmdFieldMask1Byte ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	
	if ( defectListSize > 0 )
	{
		
		// We have data to send to the device, 
		// make sure that we were given a valid buffer
		require ( IsMemoryDescriptorValid ( dataBuffer, defectListSize ), ErrorExit );
		
	}
	
	// This is a 6-Byte command, fill out the cdb appropriately  
	SetCommandDescriptorBlock (	request,
								kSCSICmd_FORMAT_UNIT,
								( FMTPINFO << 7 ) | ( RTO_REQ << 6 ) | ( LONGLIST << 5 ) | ( FMTDATA << 4 ) | ( CMPLST << 3 ) | DEFECT_LIST_FORMAT,
								VENDOR_SPECIFIC,
								0x00,
								0x00,
								CONTROL );
 	
 	if ( FMTDATA == 0 )
	{
		
		// No DEFECT LIST is being sent to the device, so there
		// will be no data transfer for this request.
		SetDataTransferDirection ( 	request, kSCSIDataTransfer_NoDataTransfer );
		SetTimeoutDuration ( request, 0 );
		
	}
	
	else
	{
		
		// The client has requested a DEFECT LIST be sent to the device
		// to be used with the format command
		SetDataTransferDirection ( 	request, kSCSIDataTransfer_FromInitiatorToTarget );
		SetTimeoutDuration ( request, 0 );
		SetDataBuffer ( request, dataBuffer );
		SetRequestedDataTransferCount ( request,  defectListSize );
		
	}
	
	status = true;
	
	
ErrorExit:
	
	
	return status;
	
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ LOCK_UNLOCK_CACHE - Builds a LOCK_UNLOCK_CACHE command.		[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::LOCK_UNLOCK_CACHE (
						SCSITaskIdentifier			request,
						SCSICmdField1Bit 			LOCK, 
						SCSICmdField1Bit 			RELADR, 
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS, 
						SCSICmdField2Byte 			NUMBER_OF_BLOCKS, 
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );

	status = GetSCSIBlockCommandObject ( )->LOCK_UNLOCK_CACHE (
				scsiRequest,
				LOCK, 
				RELADR, 
				LOGICAL_BLOCK_ADDRESS, 
				NUMBER_OF_BLOCKS, 
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ LOCK_UNLOCK_CACHE - Builds a LOCK_UNLOCK_CACHE command.		[PROTECTED]
//  Defined in SBC-2 section 5.5
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::LOCK_UNLOCK_CACHE (
						SCSITaskIdentifier			request,
						SCSICmdField1Bit 			LOCK,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField2Byte 			NUMBER_OF_BLOCKS,
						SCSICmdField1Byte 			CONTROL )
{

	bool		status 		= false;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );

	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( LOCK, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( NUMBER_OF_BLOCKS, kSCSICmdFieldMask2Byte ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	
	// This is a 12-Byte command, fill out the cdb appropriately  
	SetCommandDescriptorBlock (	request,
								kSCSICmd_LOCK_UNLOCK_CACHE,
								( LOCK << 1 ),
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8  ) & 0xFF,
								  LOGICAL_BLOCK_ADDRESS			& 0xFF,
								0x00,
								( NUMBER_OF_BLOCKS >> 8 ) 	& 0xFF,
								  NUMBER_OF_BLOCKS			& 0xFF,
								CONTROL );
	
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_NoDataTransfer );
	SetTimeoutDuration ( request, 0 );

	status = true;
	
	
ErrorExit:


	return status;

}

//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ LOCK_UNLOCK_CACHE_16 - Builds a LOCK_UNLOCK_CACHE_16 command. [PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::LOCK_UNLOCK_CACHE_16 (
						SCSITaskIdentifier			request,
						SCSICmdField1Bit			LOCK,
						SCSICmdField8Byte			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField4Byte			NUMBER_OF_BLOCKS,
						SCSICmdField1Byte			CONTROL )
{

	bool		status = false;

	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );
	
	// Do the pre-flight check on the passed in parameters.
	require( IsParameterValid( LOCK, kSCSICmdFieldMask1Bit ), ErrorExit );
	require( IsParameterValid( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask8Byte ), ErrorExit );
	require( IsParameterValid( NUMBER_OF_BLOCKS, kSCSICmdFieldMask4Byte ), ErrorExit );
	require( IsParameterValid( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	
	// This is a 16-byte command, fill out the cdb appropriately.
	SetCommandDescriptorBlock ( request,
								kSCSICmd_LOCK_UNLOCK_CACHE_16,
								LOCK << 1,
								( LOGICAL_BLOCK_ADDRESS >> 56 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 48 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 40 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 32 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
								LOGICAL_BLOCK_ADDRESS & 0xFF,
								( NUMBER_OF_BLOCKS >> 24 ) & 0xFF,
								( NUMBER_OF_BLOCKS >> 16 ) & 0xFF,
								( NUMBER_OF_BLOCKS >> 8 ) & 0xFF,
								NUMBER_OF_BLOCKS & 0xFF,
								0x00,
								CONTROL );
								
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_NoDataTransfer );
	SetTimeoutDuration ( request, 0 );
												
	status = true;
	
ErrorExit:

	
	return status;
	
}
						
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ MEDIUM_SCAN - Builds a MEDIUM_SCAN command.					[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::MEDIUM_SCAN (
						SCSITaskIdentifier			request,
				 		IOMemoryDescriptor *		dataBuffer,
			   			SCSICmdField1Bit 			WBS,
			   			SCSICmdField1Bit 			ASA,
			   			SCSICmdField1Bit 			RSD,
			   			SCSICmdField1Bit 			PRA,
						SCSICmdField1Bit 			RELADR,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField2Byte 			PARAMETER_LIST_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->MEDIUM_SCAN (
				scsiRequest,
				dataBuffer,
   				WBS,
   				ASA,
   				RSD,
   				PRA,
				RELADR,
				LOGICAL_BLOCK_ADDRESS,
				PARAMETER_LIST_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ PREFETCH - Builds a PREFETCH command.							[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::PREFETCH (
						SCSITaskIdentifier			request,
						SCSICmdField1Bit 			IMMED,
						SCSICmdField1Bit 			RELADR,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField2Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->PREFETCH (
				scsiRequest,
				IMMED,
				RELADR,
				LOGICAL_BLOCK_ADDRESS,
				TRANSFER_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ PREFETCH - Builds a PREFETCH command.							[PROTECTED]
// Defined in SBC-2 section 5.7
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::PREFETCH (
						SCSITaskIdentifier			request,
						SCSICmdField1Bit 			IMMED,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField5Bit			GROUP_NUMBER,
						SCSICmdField2Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{

	bool		status 		= false;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );

	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( IMMED, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
	require( IsParameterValid( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
	require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	
	// This is a 10-Byte command, fill out the cdb appropriately  
	SetCommandDescriptorBlock (	request,
								kSCSICmd_PREFETCH,
								( IMMED << 1 ),
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8  ) & 0xFF,
								  LOGICAL_BLOCK_ADDRESS 		& 0xFF,
								GROUP_NUMBER,
								( TRANSFER_LENGTH >> 8 ) & 0xFF,
								  TRANSFER_LENGTH		 & 0xFF,
								CONTROL );
	
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_NoDataTransfer );
	SetTimeoutDuration ( request, 0 );

	status = true;


ErrorExit:
	
	
	return status;

}

//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ PREFETCH_16 - Builds a PREFETCH_16 command.					[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::PREFETCH_16 (
						SCSITaskIdentifier			request,
						SCSICmdField1Bit			IMMED,
						SCSICmdField8Byte			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField4Byte			TRANSFER_LENGTH,
						SCSICmdField5Bit			GROUP_NUMBER,
						SCSICmdField1Byte			CONTROL )
{

	bool		status = false;

	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );
	
	// Do the pre-flight check on the passed in parameters
	require( IsParameterValid ( IMMED, kSCSICmdFieldMask1Bit ), ErrorExit );
	require( IsParameterValid( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask8Byte ), ErrorExit );
	require( IsParameterValid( TRANSFER_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
	require( IsParameterValid( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
	require( IsParameterValid( CONTROL, kSCSICmdFieldMask1Bit ), ErrorExit );
	
	// This is a 16-byte command, fill out the cdb appropriately
	SetCommandDescriptorBlock ( request,
								kSCSICmd_PREFETCH_16,
								IMMED << 1,
								( LOGICAL_BLOCK_ADDRESS >> 56 ) & 0xFF, 
								( LOGICAL_BLOCK_ADDRESS >> 48 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 40 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 32 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
								LOGICAL_BLOCK_ADDRESS & 0xFF,
								( TRANSFER_LENGTH >> 24 ) & 0xFF,
								( TRANSFER_LENGTH >> 16 ) & 0xFF,
								( TRANSFER_LENGTH >> 8 ) & 0xFF,
								TRANSFER_LENGTH & 0xFF,
								GROUP_NUMBER,
								CONTROL );
							
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_NoDataTransfer );
	SetTimeoutDuration ( request, 0 );
								
	status = true;
	
	
ErrorExit:
	
	
	return status;
	
}
		
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ READ_6 - Builds a READ_6 command.								[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::READ_6 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						UInt32						blockSize,
						SCSICmdField21Bit 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField1Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest			= NULL;
	bool		status 				= false;
	UInt32 		requestedByteCount	= 0;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	// Check the validity of the media
	require_nonzero ( blockSize, ErrorExit );
	
	if ( TRANSFER_LENGTH == 0 )
	{
		
		// The TRANSFER_LENGTH is zero, this indicates that 256 blocks
		// should be transfer from the device
		requestedByteCount = 256 * blockSize;
		
	}
	
	else
	{
		requestedByteCount = TRANSFER_LENGTH * blockSize;
	}
	
	status = GetSCSIBlockCommandObject ( )->READ_6 (
				scsiRequest,
				dataBuffer,
				requestedByteCount,
				LOGICAL_BLOCK_ADDRESS,
				TRANSFER_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ READ_10 - Builds a READ_10 command.							[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 	
IOSCSIBlockCommandsDevice::READ_10 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						UInt32						blockSize,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit			FUA,
						SCSICmdField1Bit			RELADR,
						SCSICmdField4Byte			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField2Byte			TRANSFER_LENGTH,
						SCSICmdField1Byte			CONTROL )
{
	
	SCSITask *	scsiRequest			= NULL;
	bool		status 				= false;
	UInt64		requestedByteCount	= 0;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	// Check the validity of the media
	require_nonzero ( blockSize, ErrorExit );
	
	requestedByteCount = TRANSFER_LENGTH * blockSize;
	
	status = GetSCSIBlockCommandObject ( )->READ_10 (
				scsiRequest,
				dataBuffer,
				requestedByteCount,
				DPO,
				FUA,
				RELADR,
				LOGICAL_BLOCK_ADDRESS,
				TRANSFER_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ READ_10 - Builds a READ_10 command.							[PROTECTED]
// Defined in SBC-2 section 5.10
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::READ_10 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						UInt32						blockSize,
						SCSICmdField3Bit 			RDPROTECT,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			FUA,
						SCSICmdField1Bit 			FUA_NV,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField5Bit			GROUP_NUMBER,
						SCSICmdField2Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{

	bool		status 				= false;
	UInt64		requestedByteCount	= 0;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );
	
	// Check the validity of the media
	require_nonzero ( blockSize, ErrorExit );
	
	requestedByteCount = TRANSFER_LENGTH * blockSize;
	
	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( RDPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
	require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( FUA_NV, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
	require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	require ( IsMemoryDescriptorValid ( dataBuffer, requestedByteCount  ), ErrorExit );
	
	// This is a 10-Byte command, fill out the cdb appropriately  
	SetCommandDescriptorBlock (	request,
								kSCSICmd_READ_10,
								( RDPROTECT << 5 ) | ( DPO << 4 ) | ( FUA << 3 ) | ( FUA_NV << 1 ),
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8  ) & 0xFF,
								  LOGICAL_BLOCK_ADDRESS			& 0xFF,
								GROUP_NUMBER,
								( TRANSFER_LENGTH >> 8 ) & 0xFF,
								  TRANSFER_LENGTH		 & 0xFF,
								CONTROL );
	
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_FromTargetToInitiator );
	SetTimeoutDuration ( request, 0 );
	SetDataBuffer ( request, dataBuffer );
	SetRequestedDataTransferCount ( request,  requestedByteCount );

	status = true;
	
	
ErrorExit:
	
	
	return status;
	

}

//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ READ_12 - Builds a READ_12 command.							[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 	
IOSCSIBlockCommandsDevice::READ_12 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						UInt32						blockSize,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			FUA,
						SCSICmdField1Bit 			RELADR,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField4Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest			= NULL;
	bool		status 				= false;
	UInt64 		requestedByteCount	= 0;

	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	// Check the validity of the media
	require_nonzero ( blockSize, ErrorExit );
	
	requestedByteCount = TRANSFER_LENGTH * blockSize;
	
	status = GetSCSIBlockCommandObject ( )->READ_12 (
				scsiRequest,
				dataBuffer,
				requestedByteCount,
				DPO,
				FUA,
				RELADR,
				LOGICAL_BLOCK_ADDRESS,
				TRANSFER_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ READ_12 - Builds a READ_12 command.							[PROTECTED]
//  Defined in SBC-2 section 5.11
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::READ_12 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						UInt32						blockSize,
						SCSICmdField3Bit			RDPROTECT,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			FUA,
						SCSICmdField1Bit 			FUA_NV,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField4Byte 			TRANSFER_LENGTH,
						SCSICmdField5Bit			GROUP_NUMBER,
						SCSICmdField1Byte 			CONTROL )
{
	
	bool		status 				= false;
	UInt64 		requestedByteCount	= 0;

	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );
	
	// Check the validity of the media
	require_nonzero ( blockSize, ErrorExit );
	
	requestedByteCount = TRANSFER_LENGTH * blockSize;

	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( RDPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
	require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( FUA_NV, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	require ( IsMemoryDescriptorValid ( dataBuffer, requestedByteCount  ), ErrorExit );
	
	// This is a 12-Byte command, fill out the cdb appropriately  
	SetCommandDescriptorBlock (	request,
								kSCSICmd_READ_12,
								( RDPROTECT << 5 ) | ( DPO << 4 ) | ( FUA << 3 ) | ( FUA_NV << 1 ),
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8  ) & 0xFF,
								  LOGICAL_BLOCK_ADDRESS			& 0xFF,
								( TRANSFER_LENGTH >> 24 ) 		& 0xFF,
								( TRANSFER_LENGTH >> 16 ) 		& 0xFF,
								( TRANSFER_LENGTH >> 8  ) 		& 0xFF,
								  TRANSFER_LENGTH				& 0xFF,
								GROUP_NUMBER,
								CONTROL );
	
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_FromTargetToInitiator );
	SetTimeoutDuration ( request, 0 );
	SetDataBuffer ( request, dataBuffer );
	SetRequestedDataTransferCount ( request,  requestedByteCount );

	status = true;


ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ READ_16 - Builds a READ_16 command.							[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::READ_16 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						UInt32						blockSize,
						SCSICmdField3Bit			RDPROTECT,
						SCSICmdField1Bit			DPO,
						SCSICmdField1Bit			FUA,
						SCSICmdField1Bit			FUA_NV,
						SCSICmdField8Byte			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField4Byte			TRANSFER_LENGTH,
						SCSICmdField5Bit			GROUP_NUMBER,
						SCSICmdField1Byte			CONTROL )
{

	bool		status = false;
	UInt64 		requestedByteCount	= 0;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );

	// Check the validity of the media
	require_nonzero ( blockSize, ErrorExit );

	requestedByteCount = TRANSFER_LENGTH * blockSize;
	
	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( RDPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
	require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( FUA_NV, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask8Byte ), ErrorExit );
	require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	require ( IsMemoryDescriptorValid ( dataBuffer, requestedByteCount ), ErrorExit );
	
	// This is a 16-Byte command, fill out the cdb appropriately
	SetCommandDescriptorBlock ( request,
								kSCSICmd_READ_16,
								( RDPROTECT << 5 ) | ( DPO << 4 ) | ( FUA << 3 ) | ( FUA_NV << 1 ),
								( LOGICAL_BLOCK_ADDRESS >> 56 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 48 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 40 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 32 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
								LOGICAL_BLOCK_ADDRESS & 0xFF,
								( TRANSFER_LENGTH >> 24 ) & 0xFF,
								( TRANSFER_LENGTH >> 16 ) & 0xFF,
								( TRANSFER_LENGTH >> 8 ) & 0xFF,
								TRANSFER_LENGTH & 0xFF,
								GROUP_NUMBER,
								CONTROL );
								
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_FromTargetToInitiator );
	SetTimeoutDuration ( request, 0 );
	SetDataBuffer ( request, dataBuffer );
	SetRequestedDataTransferCount ( request,  requestedByteCount );

	status = true;
	
	
ErrorExit:


	return status;
	
}
		
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ READ_CAPACITY - Builds a READ_CAPACITY command.				[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::READ_CAPACITY (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField1Bit 			RELADR,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField1Bit 			PMI,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->READ_CAPACITY (
				scsiRequest,
				dataBuffer,
				RELADR,
				LOGICAL_BLOCK_ADDRESS,
				PMI,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}

//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ READ_CAPACITY_16 - Builds a READ_CAPACITY_16 command.			[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::READ_CAPACITY_16 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField8Byte			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField4Byte			ALLOCATION_LENGTH,
						SCSICmdField1Bit			PMI,
						SCSICmdField1Byte			CONTROL )
{

	bool		status  = false;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );
	
	// Do the pre-flight check on the passed parameters
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask8Byte ), ErrorExit );
	require ( IsParameterValid ( ALLOCATION_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( PMI, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	require ( IsMemoryDescriptorValid ( dataBuffer, ALLOCATION_LENGTH ), ErrorExit );
	
	// This is a 16 byte command, fill out the cdb appropriately.
	SetCommandDescriptorBlock ( request,
								kSCSICmd_SERVICE_ACTION_IN,
								kSCSIServiceAction_READ_CAPACITY_16,
								( LOGICAL_BLOCK_ADDRESS >> 56 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 48 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 40 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 32 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
								LOGICAL_BLOCK_ADDRESS & 0xFF,
								( ALLOCATION_LENGTH >> 24 ) & 0xFF,
								( ALLOCATION_LENGTH >> 16 ) & 0xFF,
								( ALLOCATION_LENGTH >> 8 ) & 0xFF,
								ALLOCATION_LENGTH & 0xFF,
								PMI,
								CONTROL );
								
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_FromTargetToInitiator );
	SetTimeoutDuration ( request, 0 );
	SetDataBuffer ( request, dataBuffer );
	SetRequestedDataTransferCount ( request,  ALLOCATION_LENGTH );

	status = true;
	
ErrorExit:

	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ READ_DEFECT_DATA_10 - Builds a READ_DEFECT_DATA_10 command.	[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::READ_DEFECT_DATA_10 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField1Bit 			PLIST,
						SCSICmdField1Bit 			GLIST,
						SCSICmdField3Bit 			DEFECT_LIST_FORMAT,
						SCSICmdField2Byte 			ALLOCATION_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->READ_DEFECT_DATA_10 (
				scsiRequest,
				dataBuffer,
				PLIST,
				GLIST,
				DEFECT_LIST_FORMAT,
				ALLOCATION_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ READ_DEFECT_DATA_12 - Builds a READ_DEFECT_DATA_12 command.	[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::READ_DEFECT_DATA_12 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField1Bit 			PLIST,
						SCSICmdField1Bit 			GLIST,
						SCSICmdField3Bit 			DEFECT_LIST_FORMAT,
						SCSICmdField4Byte 			ALLOCATION_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->READ_DEFECT_DATA_12 (
				scsiRequest,
				dataBuffer,
				PLIST,
				GLIST,
				DEFECT_LIST_FORMAT,
				ALLOCATION_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ READ_GENERATION - Builds a READ_GENERATION command.			[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::READ_GENERATION (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField1Bit 			RELADR,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField1Byte 			ALLOCATION_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->READ_GENERATION (
				scsiRequest,
				dataBuffer,
				RELADR,
				LOGICAL_BLOCK_ADDRESS,
				ALLOCATION_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ READ_LONG - Builds a READ_LONG command.						[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::READ_LONG (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField1Bit 			CORRCT,
						SCSICmdField1Bit 			RELADR,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField2Byte 			BYTE_TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->READ_LONG (
				scsiRequest,
				dataBuffer,
				CORRCT,
				RELADR,
				LOGICAL_BLOCK_ADDRESS,
				BYTE_TRANSFER_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}

//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ READ_LONG_16 - Builds a READ_LONG_16 command.					[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::READ_LONG_16 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField8Byte			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField2Byte			BYTE_TRANSFER_LENGTH,
						SCSICmdField1Bit			CORRCT,
						SCSICmdField1Byte			CONTROL )
{

	bool		status 		= false;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );
	
	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask8Byte ), ErrorExit );
	require ( IsParameterValid ( BYTE_TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
	require ( IsParameterValid ( CORRCT, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	require ( IsMemoryDescriptorValid ( dataBuffer, BYTE_TRANSFER_LENGTH ), ErrorExit );

	// This is a 16-Byte command, fill out the cdb appropriately 
	SetCommandDescriptorBlock ( request,
								kSCSICmd_SERVICE_ACTION_IN,
								kSCSIServiceAction_READ_LONG_16,
								( LOGICAL_BLOCK_ADDRESS >> 56 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 48 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 40 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 32 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
								LOGICAL_BLOCK_ADDRESS & 0xFF,
								0x00,
								0x00,
								( BYTE_TRANSFER_LENGTH >> 8 ) & 0xFF,
								BYTE_TRANSFER_LENGTH & 0xFF,
								CORRCT,
								CONTROL );
								
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_FromTargetToInitiator );
	SetTimeoutDuration ( request, 0 );
	SetDataBuffer ( request, dataBuffer );
	SetRequestedDataTransferCount ( request,  BYTE_TRANSFER_LENGTH );

	status = true;
	
ErrorExit:


	return status;
	
}
		
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ READ_UPDATED_BLOCK_10 - Builds a READ_UPDATED_BLOCK_10 command.
//																	[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::READ_UPDATED_BLOCK_10 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			FUA,
					 	SCSICmdField1Bit 			RELADR,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField1Bit 			LATEST,
					 	SCSICmdField15Bit 			GENERATION_ADDRESS,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->READ_UPDATED_BLOCK_10 (
				scsiRequest,
				dataBuffer,
				fMediumBlockSize,
				DPO,
				FUA,
			 	RELADR,
				LOGICAL_BLOCK_ADDRESS,
				LATEST,
			 	GENERATION_ADDRESS,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ REASSIGN_BLOCKS - Builds a REASSIGN_BLOCKS command.			[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::REASSIGN_BLOCKS (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->REASSIGN_BLOCKS (
				scsiRequest,
				dataBuffer,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ REASSIGN_BLOCKS - Builds a REASSIGN_BLOCKS command.			[PROTECTED]
//  Defined in SBC-2 section 5.20
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::REASSIGN_BLOCKS (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField1Bit			LONGLBA,
						SCSICmdField1Bit			LONGLIST,
						SCSICmdField1Byte 			CONTROL )
{

	bool		status 		= false;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );
	
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	require ( IsParameterValid ( LONGLBA, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LONGLIST, kSCSICmdFieldMask1Bit ), ErrorExit );
	
	// This is a 6-Byte command, fill out the cdb appropriately  
	SetCommandDescriptorBlock (	request,
								kSCSICmd_REASSIGN_BLOCKS,
								( LONGLBA << 1 ) | LONGLIST,
								0x00,
								0x00,
								0x00,
								CONTROL );
	
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_NoDataTransfer );
	SetTimeoutDuration ( request, 0 );

	status = true;
	
	
ErrorExit:
	
	
	return status;
	

}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ REBUILD - Builds a REBUILD command.							[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::REBUILD (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			FUA,
					 	SCSICmdField1Bit 			INTDATA,
						SCSICmdField2Bit 			PORT_CONTROL,
					 	SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField4Byte 			REBUILD_LENGTH,
						SCSICmdField4Byte 			PARAMETER_LIST_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->REBUILD (
				scsiRequest,
				dataBuffer,
				DPO,
				FUA,
			 	INTDATA,
				PORT_CONTROL,
			 	LOGICAL_BLOCK_ADDRESS,
				REBUILD_LENGTH,
				PARAMETER_LIST_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ REGENERATE - Builds a REGENERATE command.						[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::REGENERATE (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField1Bit			DPO,
						SCSICmdField1Bit 			FUA,
					 	SCSICmdField1Bit 			INTDATA,
					 	SCSICmdField2Bit 			PORT_CONTROL,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField4Byte 			REBUILD_LENGTH,
						SCSICmdField4Byte 			PARAMETER_LIST_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->REGENERATE (
				scsiRequest,
				dataBuffer,
				DPO,
				FUA,
			 	INTDATA,
			 	PORT_CONTROL,
				LOGICAL_BLOCK_ADDRESS,
				REBUILD_LENGTH,
				PARAMETER_LIST_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ REZERO_UNIT - Builds a REZERO_UNIT command.					[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::REZERO_UNIT ( 
						SCSITaskIdentifier			request,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->REZERO_UNIT (
					scsiRequest,
					CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ SEARCH_DATA_EQUAL_10 - Builds a SEARCH_DATA_EQUAL_10 command.	[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::SEARCH_DATA_EQUAL_10 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField1Bit 			INVERT,
						SCSICmdField1Bit 			SPNDAT,
						SCSICmdField1Bit 			RELADR,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField2Byte 			NUMBER_OF_BLOCKS_TO_SEARCH,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->SEARCH_DATA_EQUAL_10 (
				scsiRequest,
				dataBuffer,
				dataBuffer->getLength ( ),
				INVERT,
				SPNDAT,
				RELADR,
				LOGICAL_BLOCK_ADDRESS,
				NUMBER_OF_BLOCKS_TO_SEARCH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ SEARCH_DATA_HIGH_10 - Builds a SEARCH_DATA_HIGH_10 command.	[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::SEARCH_DATA_HIGH_10 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField1Bit 			INVERT,
						SCSICmdField1Bit 			SPNDAT,
						SCSICmdField1Bit 			RELADR,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField2Byte 			NUMBER_OF_BLOCKS_TO_SEARCH,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->SEARCH_DATA_HIGH_10 (
				scsiRequest,
				dataBuffer,
				dataBuffer->getLength ( ),
				INVERT,
				SPNDAT,
				RELADR,
				LOGICAL_BLOCK_ADDRESS,
				NUMBER_OF_BLOCKS_TO_SEARCH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ SEARCH_DATA_LOW_10 - Builds a SEARCH_DATA_LOW_10 command.		[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::SEARCH_DATA_LOW_10 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField1Bit 			INVERT,
						SCSICmdField1Bit 			SPNDAT,
						SCSICmdField1Bit 			RELADR,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField2Byte 			NUMBER_OF_BLOCKS_TO_SEARCH,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->SEARCH_DATA_LOW_10 (
				scsiRequest,
				dataBuffer,
				dataBuffer->getLength ( ),
				INVERT,
				SPNDAT,
				RELADR,
				LOGICAL_BLOCK_ADDRESS,
				NUMBER_OF_BLOCKS_TO_SEARCH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ SEEK_6 - Builds a SEEK_6 command.								[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::SEEK_6 (
						SCSITaskIdentifier			request,
						SCSICmdField21Bit 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->SEEK_6 (
				scsiRequest,
				LOGICAL_BLOCK_ADDRESS, 
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ SEEK_10 - Builds a SEEK_10 command.							[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::SEEK_10 (
						SCSITaskIdentifier			request,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->SEEK_10 (
				scsiRequest,
				LOGICAL_BLOCK_ADDRESS,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ SET_LIMITS_10 - Builds a SET_LIMITS_10 command.				[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::SET_LIMITS_10 (
						SCSITaskIdentifier			request,
						SCSICmdField1Bit 			RDINH,
						SCSICmdField1Bit 			WRINH,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField2Byte 			NUMBER_OF_BLOCKS,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->SET_LIMITS_10 (
				scsiRequest,
				RDINH,
				WRINH,
				LOGICAL_BLOCK_ADDRESS,
				NUMBER_OF_BLOCKS,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ SET_LIMITS_12 - Builds a SET_LIMITS_12 command.				[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::SET_LIMITS_12 (
						SCSITaskIdentifier			request,
						SCSICmdField1Bit 			RDINH,
						SCSICmdField1Bit 			WRINH,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField4Byte 			NUMBER_OF_BLOCKS,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->SET_LIMITS_12 (
				scsiRequest,
				RDINH,
				WRINH,
				LOGICAL_BLOCK_ADDRESS,
				NUMBER_OF_BLOCKS,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ START_STOP_UNIT - Builds a START_STOP_UNIT command.			[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::START_STOP_UNIT (
						SCSITaskIdentifier			request,
						SCSICmdField1Bit 			IMMED,
						SCSICmdField4Bit 			POWER_CONDITIONS,
						SCSICmdField1Bit 			LOEJ,
						SCSICmdField1Bit 			START,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->START_STOP_UNIT (
				scsiRequest,
				IMMED,
				POWER_CONDITIONS,
				LOEJ,
				START,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ SYNCHRONIZE_CACHE - Builds a SYNCHRONIZE_CACHE command.		[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::SYNCHRONIZE_CACHE (
						SCSITaskIdentifier			request,
						SCSICmdField1Bit 			IMMED,
						SCSICmdField1Bit 			RELADR,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField2Byte 			NUMBER_OF_BLOCKS,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->SYNCHRONIZE_CACHE (
				scsiRequest,
				IMMED,
				RELADR,
				LOGICAL_BLOCK_ADDRESS,
				NUMBER_OF_BLOCKS,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ SYNCHRONIZE_CACHE - Builds a SYNCHRONIZE_CACHE command.		[PROTECTED]
//  Defined in SBC-2 section 5.22
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::SYNCHRONIZE_CACHE (
						SCSITaskIdentifier			request,
						SCSICmdField1Bit 			IMMED,
						SCSICmdField1Bit 			SYNC_NV,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField5Bit			GROUP_NUMBER,
						SCSICmdField2Byte 			NUMBER_OF_BLOCKS,
						SCSICmdField1Byte 			CONTROL )
{

	bool		status 		= false;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );
	
	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( IMMED, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( SYNC_NV, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
	require ( IsParameterValid ( NUMBER_OF_BLOCKS, kSCSICmdFieldMask2Byte ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	
	// This is a 6-Byte command, fill out the cdb appropriately
	SetCommandDescriptorBlock (	request,
								kSCSICmd_SYNCHRONIZE_CACHE,
								( SYNC_NV << 2 ) | ( IMMED << 1 ),
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8  ) & 0xFF,
								  LOGICAL_BLOCK_ADDRESS			& 0xFF,
								GROUP_NUMBER,
								( NUMBER_OF_BLOCKS >> 8 )	& 0xFF,
								  NUMBER_OF_BLOCKS			& 0xFF,
								CONTROL );
	
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_NoDataTransfer );
	SetTimeoutDuration ( request, 0 );
								
	status = true;
	
ErrorExit:
	
	
	return status;
	

}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ SYNCRONIZE_CACHE_16 - Builds a SYNCRONIZE_CACHE_16 command.   [PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::SYNCRONIZE_CACHE_16 (
						SCSITaskIdentifier			request,
						SCSICmdField1Bit			SYNC_NV,
						SCSICmdField1Bit			IMMED,
						SCSICmdField8Byte			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField4Byte			NUMBER_OF_BLOCKS,
						SCSICmdField5Bit			GROUP_NUMBER,
						SCSICmdField1Byte			CONTROL )
{

	bool		status 		= false;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );

	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( SYNC_NV, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( IMMED, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask8Byte ), ErrorExit );
	require ( IsParameterValid ( NUMBER_OF_BLOCKS, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	
	// This is a 16-Byte command, fill out the cdb appropriately
	SetCommandDescriptorBlock ( request,
								kSCSICmd_SYNCHRONIZE_CACHE_16,
								( SYNC_NV << 2 ) | ( IMMED << 1 ),
								( LOGICAL_BLOCK_ADDRESS >> 56 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 48 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 40 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 32 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
								LOGICAL_BLOCK_ADDRESS & 0xFF,
								( NUMBER_OF_BLOCKS >> 24 ) & 0xFF,
								( NUMBER_OF_BLOCKS >> 16 ) & 0xFF,
								( NUMBER_OF_BLOCKS >> 8 ) & 0xFF,
								NUMBER_OF_BLOCKS & 0xFF,
								GROUP_NUMBER,
								CONTROL );

	SetDataTransferDirection ( 	request, kSCSIDataTransfer_NoDataTransfer );
	SetTimeoutDuration ( request, 0 );

	status = true;
	
	
ErrorExit:

	
	return status;
	
}
						
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ UPDATE_BLOCK - Builds a UPDATE_BLOCK command.					[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::UPDATE_BLOCK (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField1Bit 			RELADR,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->UPDATE_BLOCK (
				scsiRequest,
				dataBuffer,
				fMediumBlockSize,
				RELADR, 
				LOGICAL_BLOCK_ADDRESS, 
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ VERIFY_10 - Builds a VERIFY_10 command.						[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::VERIFY_10 (
						SCSITaskIdentifier			request,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			BLKVFY,
						SCSICmdField1Bit 			BYTCHK,
						SCSICmdField1Bit 			RELADR,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField2Byte 			VERIFICATION_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->VERIFY_10 (
				scsiRequest,
				DPO,
				BLKVFY,
				BYTCHK,
				RELADR,
				LOGICAL_BLOCK_ADDRESS,
				VERIFICATION_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ VERIFY_10 - Builds a VERIFY_10 command.						[PROTECTED]
//  Defined in SBC-2 section 5.24
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::VERIFY_10 (
						SCSITaskIdentifier			request,
						SCSICmdField3Bit 			VRPROTECT,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			BYTCHK,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField5Bit			GROUP_NUMBER,
						SCSICmdField2Byte 			VERIFICATION_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{

	bool		status 		= false;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );

	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( VRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
	require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( BYTCHK, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
	require ( IsParameterValid ( VERIFICATION_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	
	// This is a 10-Byte command, fill out the cdb appropriately
	SetCommandDescriptorBlock (	request,
								kSCSICmd_VERIFY_10,
								( VRPROTECT << 5 ) | ( DPO << 4 ) | ( BYTCHK << 1 ),
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8  ) & 0xFF,
								  LOGICAL_BLOCK_ADDRESS			& 0xFF,
								GROUP_NUMBER,
								( VERIFICATION_LENGTH >> 8 )	& 0xFF,
								  VERIFICATION_LENGTH			& 0xFF,
								CONTROL );
	
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_NoDataTransfer );
	SetTimeoutDuration ( request, 0 );

	status = true;
	
	
ErrorExit:
	
	
	return status;
	

}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ VERIFY_12 - Builds a VERIFY_12 command.						[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::VERIFY_12 (
						SCSITaskIdentifier			request,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			BLKVFY,
						SCSICmdField1Bit 			BYTCHK,
						SCSICmdField1Bit 			RELADR,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField4Byte 			VERIFICATION_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->VERIFY_12 (
				scsiRequest,
				DPO,
				BLKVFY,
				BYTCHK,
				RELADR,
				LOGICAL_BLOCK_ADDRESS,
				VERIFICATION_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ VERIFY_12 - Builds a VERIFY_12 command.						[PROTECTED]
//  Defined in SBC-2 section 5.25
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::VERIFY_12 (
						SCSITaskIdentifier			request,
						SCSICmdField3Bit 			VRPROTECT,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			BYTCHK,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField5Bit			GROUP_NUMBER,
						SCSICmdField4Byte 			VERIFICATION_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{

	bool		status 		= false;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );
	
	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( VRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
	require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( BYTCHK, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );	
	require ( IsParameterValid ( VERIFICATION_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	
	// This is a 10-Byte command, fill out the cdb appropriately
	SetCommandDescriptorBlock (	request,
								kSCSICmd_VERIFY_12,
								( VRPROTECT << 5 ) | ( DPO << 4 ) | ( BYTCHK << 1 ),
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8  ) & 0xFF,
								  LOGICAL_BLOCK_ADDRESS			& 0xFF,
								( VERIFICATION_LENGTH >> 24 )	& 0xFF,
								( VERIFICATION_LENGTH >> 16 )	& 0xFF,
								( VERIFICATION_LENGTH >>  8 )	& 0xFF,
								  VERIFICATION_LENGTH			& 0xFF,
								0x00,
								CONTROL );
	
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_NoDataTransfer );
	SetTimeoutDuration ( request, 0 );
	
	status = true;
	
	
ErrorExit:
	
	
	return status;
	

}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ VERIFY_16 - Builds a VERIFY_16 command.						[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::VERIFY_16 (
						SCSITaskIdentifier			request,
						SCSICmdField3Bit			VRPROTECT,
						SCSICmdField1Bit			DPO,
						SCSICmdField1Bit			BYTCHK,
						SCSICmdField8Byte			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField4Byte			VERIFICATION_LENGTH,
						SCSICmdField5Bit			GROUP_NUMBER,
						SCSICmdField1Byte			CONTROL )
{

	bool		status 		= false;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );
	
	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( VRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
	require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( BYTCHK, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask8Byte ), ErrorExit );
	require ( IsParameterValid ( VERIFICATION_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	
	// This is a 16-Byte command, fill out the cdb appropriately
	SetCommandDescriptorBlock ( request,
								kSCSICmd_VERIFY_16,
								( VRPROTECT << 5 ) | ( DPO << 4 ) | ( BYTCHK << 1 ),
								( LOGICAL_BLOCK_ADDRESS >> 56 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 48 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 40 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 32 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
								LOGICAL_BLOCK_ADDRESS & 0xFF,
								( VERIFICATION_LENGTH >> 24 ) & 0xFF,
								( VERIFICATION_LENGTH >> 16 ) & 0xFF,
								( VERIFICATION_LENGTH >> 8 ) & 0xFF,
								VERIFICATION_LENGTH & 0xFF,
								GROUP_NUMBER,
								CONTROL );

	SetDataTransferDirection ( 	request, kSCSIDataTransfer_NoDataTransfer );
	SetTimeoutDuration ( request, 0 );
									
	status = true;
	

ErrorExit:


	return status;
	
}
	
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ WRITE_6 - Builds a WRITE_6 command.							[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::WRITE_6 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						UInt32						blockSize,
						SCSICmdField2Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField1Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{
		
	SCSITask *	scsiRequest			= NULL;
	bool		status 				= false;
	UInt32 		requestedByteCount	= 0;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	// Check the validity of the media
	require_nonzero ( blockSize, ErrorExit );
	
	if ( TRANSFER_LENGTH == 0 )
	{
		
		// The TRANSFER_LENGTH is zero, this indicates that 256 blocks
		// should be transfer from the device
		requestedByteCount = 256 * blockSize;
		
	}
	
	else
	{
		requestedByteCount = TRANSFER_LENGTH * blockSize;
	}
	
	status = GetSCSIBlockCommandObject ( )->WRITE_6 (
				scsiRequest,
				dataBuffer,
				requestedByteCount,
				LOGICAL_BLOCK_ADDRESS,
				TRANSFER_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ WRITE_10 - Builds a WRITE_10 command.							[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ


bool
IOSCSIBlockCommandsDevice::WRITE_10 (
						SCSITaskIdentifier			request,
		   				IOMemoryDescriptor *		dataBuffer,
						UInt32						blockSize,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			FUA,
						SCSICmdField1Bit 			EBP,
						SCSICmdField1Bit 			RELADR,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField2Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{
		
	SCSITask *	scsiRequest			= NULL;
	bool		status 				= false;
	UInt64 		requestedByteCount	= 0;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	// Check the validity of the media
	require_nonzero ( blockSize, ErrorExit );
	
	requestedByteCount = TRANSFER_LENGTH * blockSize;
	
	status = GetSCSIBlockCommandObject ( )->WRITE_10 (
				scsiRequest,
				dataBuffer,
				requestedByteCount,
				DPO,
				FUA,
				EBP,
				RELADR,
				LOGICAL_BLOCK_ADDRESS,
				TRANSFER_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ WRITE_10 - Builds a WRITE_10 command.							[PROTECTED]
//  Defined in SBC-2 section 5.29
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::WRITE_10 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						UInt32						blockSize,
						SCSICmdField3Bit			WRPROTECT,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			FUA,
						SCSICmdField1Bit 			FUA_NV,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField5Bit			GROUP_NUMBER,
						SCSICmdField2Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{

	bool		status 				= false;
	UInt64 		requestedByteCount	= 0;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );
	
	// Check the validity of the media
	require_nonzero ( blockSize, ErrorExit );
	
	requestedByteCount = TRANSFER_LENGTH * blockSize;
	
	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( WRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
	require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( FUA_NV, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
	require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	require ( IsMemoryDescriptorValid ( dataBuffer, requestedByteCount ), ErrorExit );
	
	// This is a 10-Byte command, fill out the cdb appropriately  
	SetCommandDescriptorBlock (	request,
								kSCSICmd_WRITE_10,
								( WRPROTECT << 5 ) | ( DPO << 4 ) | ( FUA << 3 ) | ( FUA_NV << 1 ),
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8  ) & 0xFF,
								  LOGICAL_BLOCK_ADDRESS			& 0xFF,
								GROUP_NUMBER,
								( TRANSFER_LENGTH >> 8 ) & 0xFF,
								  TRANSFER_LENGTH		 & 0xFF,
								CONTROL );
	
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_FromInitiatorToTarget );
	SetTimeoutDuration ( request, 0 );
	SetDataBuffer ( request, dataBuffer );
	SetRequestedDataTransferCount ( request,  requestedByteCount );

	status = true;
	
	
ErrorExit:
	
	
	return status;
	

}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ WRITE_12 - Builds a WRITE_12 command.							[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::WRITE_12 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						UInt32						blockSize,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			FUA,
						SCSICmdField1Bit 			EBP,
						SCSICmdField1Bit 			RELADR,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField4Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{
		
	SCSITask *	scsiRequest			= NULL;
	bool		status 				= false;
	UInt64 		requestedByteCount	= 0;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	// Check the validity of the media
	require_nonzero ( blockSize, ErrorExit );
	
	requestedByteCount = TRANSFER_LENGTH * blockSize;
	
	status = GetSCSIBlockCommandObject ( )->WRITE_12 (
				scsiRequest,
				dataBuffer,
				requestedByteCount,
				DPO,
				FUA,
				EBP,
				RELADR,
				LOGICAL_BLOCK_ADDRESS,
				TRANSFER_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ WRITE_12 - Builds a WRITE_12 command.							[PROTECTED]
//  Defined in SBC-2 section 5.30
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::WRITE_12 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						UInt32						blockSize,
						SCSICmdField3Bit			WRPROTECT,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			FUA,
						SCSICmdField1Bit 			FUA_NV,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField5Bit			GROUP_NUMBER,
						SCSICmdField4Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{

	bool		status 				= false;
	UInt64 		requestedByteCount	= 0;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );
	
	// Check the validity of the media
	require_nonzero ( blockSize, ErrorExit );
	
	requestedByteCount = TRANSFER_LENGTH * blockSize;

	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( WRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
	require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( FUA_NV, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
	require ( IsMemoryDescriptorValid ( dataBuffer, requestedByteCount ), ErrorExit );
	
	// This is a 12-Byte command, fill out the cdb appropriately  
	SetCommandDescriptorBlock (	request,
								kSCSICmd_WRITE_12,
								( WRPROTECT << 5 ) | ( DPO << 4 ) | ( FUA << 3 ) | ( FUA_NV << 1 ),
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8  ) & 0xFF,
								  LOGICAL_BLOCK_ADDRESS			& 0xFF,
								( TRANSFER_LENGTH >> 24 )		& 0xFF,
								( TRANSFER_LENGTH >> 16 )		& 0xFF,
								( TRANSFER_LENGTH >>  8 )		& 0xFF,
								  TRANSFER_LENGTH				& 0xFF,
								GROUP_NUMBER,
								CONTROL );
	
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_FromInitiatorToTarget );
	SetTimeoutDuration ( request, 0 );
	SetDataBuffer ( request, dataBuffer );
	SetRequestedDataTransferCount ( request,  requestedByteCount );

	status = true;
	
	
ErrorExit:
	
	
	return status;
	

}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ WRITE_16 - Builds a WRITE_16 command.							[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::WRITE_16 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						UInt32						blockSize,
						SCSICmdField3Bit			WRPROTECT,
						SCSICmdField1Bit			DPO,
						SCSICmdField1Bit			FUA,
						SCSICmdField1Bit			FUA_NV,
						SCSICmdField8Byte			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField4Byte			TRANSFER_LENGTH,
						SCSICmdField5Bit			GROUP_NUMBER,
						SCSICmdField1Byte			CONTROL )
{

	bool		status 				= false;
	UInt64 		requestedByteCount	= 0;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );
	
	// Check the validity of the media
	require_nonzero ( blockSize, ErrorExit );
	
	requestedByteCount = TRANSFER_LENGTH * blockSize;

	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( WRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
	require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( FUA_NV, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask8Byte ), ErrorExit );
	require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	require ( IsMemoryDescriptorValid ( dataBuffer, requestedByteCount ), ErrorExit );
	
	// This is a 16-Byte command, fill out the cdb appropriately
	SetCommandDescriptorBlock ( request,
								kSCSICmd_WRITE_16,
								( WRPROTECT << 5 ) | ( DPO << 4 ) | ( FUA << 3 ) | ( FUA_NV << 1 ),
								( LOGICAL_BLOCK_ADDRESS >> 56 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 48 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 40 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 32 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
								LOGICAL_BLOCK_ADDRESS & 0xFF,
								( TRANSFER_LENGTH >> 24 ) & 0xFF,
								( TRANSFER_LENGTH >> 16 ) & 0xFF,
								( TRANSFER_LENGTH >> 8 ) & 0xFF,
								TRANSFER_LENGTH & 0xFF,
								GROUP_NUMBER,
								CONTROL );
	
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_FromInitiatorToTarget );
	SetTimeoutDuration ( request, 0 );
	SetDataBuffer ( request, dataBuffer );
	SetRequestedDataTransferCount ( request,  requestedByteCount );

	status = true;
	
	
ErrorExit:


	return status;
	
}

//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ WRITE_AND_VERIFY_10 - Builds a WRITE_AND_VERIFY_10 command.	[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::WRITE_AND_VERIFY_10 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						UInt32						blockSize,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			EBP,
						SCSICmdField1Bit 			BYTCHK,
						SCSICmdField1Bit 			RELADR,
						SCSICmdField4Byte			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField2Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{
		
	SCSITask *	scsiRequest			= NULL;
	bool		status 				= false;
	UInt64 		requestedByteCount	= 0;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	// Check the validity of the media
	require_nonzero ( blockSize, ErrorExit );
	
	requestedByteCount = TRANSFER_LENGTH * blockSize;
	
	status = GetSCSIBlockCommandObject ( )->WRITE_AND_VERIFY_10 (
				scsiRequest,
				dataBuffer,
				requestedByteCount,
				DPO,
				EBP,
				BYTCHK,
				RELADR,
				LOGICAL_BLOCK_ADDRESS,
				TRANSFER_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ WRITE_AND_VERIFY_10 - Builds a WRITE_AND_VERIFY_10 command.	[PROTECTED]
//  Defined in SBC-2 section 5.33
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::WRITE_AND_VERIFY_10 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						UInt32						blockSize,
						SCSICmdField3Bit			WRPROTECT,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			BYTCHK,
						SCSICmdField4Byte			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField5Bit			GROUP_NUMBER,
						SCSICmdField2Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{

	bool		status 				= false;
	UInt64 		requestedByteCount	= 0;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );
	
	// Check the validity of the media
	require_nonzero ( blockSize, ErrorExit );
	
	requestedByteCount = TRANSFER_LENGTH * blockSize;

	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( WRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
	require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( BYTCHK, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
	require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	require ( IsMemoryDescriptorValid ( dataBuffer, requestedByteCount ), ErrorExit );

	// This is a 10-Byte command, fill out the cdb appropriately  
	SetCommandDescriptorBlock (	request,
								kSCSICmd_WRITE_AND_VERIFY_10,
								( WRPROTECT << 5 ) | ( DPO << 4 ) | ( BYTCHK << 1 ),
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8  ) & 0xFF,
								  LOGICAL_BLOCK_ADDRESS			& 0xFF,
								GROUP_NUMBER,
								( TRANSFER_LENGTH >> 8 )		& 0xFF,
								  TRANSFER_LENGTH				& 0xFF,
								CONTROL );
	
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_FromInitiatorToTarget );
	SetTimeoutDuration ( request, 0 );
	SetDataBuffer ( request, dataBuffer );
	SetRequestedDataTransferCount ( request,  requestedByteCount );
	
	status = true;
	
	
ErrorExit:
	
	
	return status;

}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ WRITE_AND_VERIFY_12 - Builds a WRITE_AND_VERIFY_12 command.	[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::WRITE_AND_VERIFY_12 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						UInt32						blockSize,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			EBP,
						SCSICmdField1Bit 			BYTCHK,
						SCSICmdField1Bit 			RELADR,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField4Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{
		
	SCSITask *	scsiRequest			= NULL;
	bool		status 				= false;
	UInt64 		requestedByteCount	= 0;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	// Check the validity of the media
	require_nonzero ( blockSize, ErrorExit );
	
	requestedByteCount = TRANSFER_LENGTH * blockSize;
	
	status = GetSCSIBlockCommandObject ( )->WRITE_AND_VERIFY_12 (
				scsiRequest,
				dataBuffer,
				requestedByteCount,
				DPO,
				EBP,
				BYTCHK,
				RELADR,
				LOGICAL_BLOCK_ADDRESS,
				TRANSFER_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ WRITE_AND_VERIFY_12 - Builds a WRITE_AND_VERIFY_12 command.	[PROTECTED]
//  Defined in SBC-2 section 5.34
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::WRITE_AND_VERIFY_12 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						UInt32						blockSize,
						SCSICmdField3Bit			WRPROTECT,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			BYTCHK,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField4Byte 			TRANSFER_LENGTH,
						SCSICmdField5Bit			GROUP_NUMBER,
						SCSICmdField1Byte 			CONTROL )
{

	bool		status 				= false;
	UInt64 		requestedByteCount	= 0;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );
	
	// Check the validity of the media
	require_nonzero ( blockSize, ErrorExit );
	
	requestedByteCount = TRANSFER_LENGTH * blockSize;

	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( WRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
	require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( BYTCHK, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
	require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	require ( IsMemoryDescriptorValid ( dataBuffer, requestedByteCount ), ErrorExit );

	// This is a 12-Byte command, fill out the cdb appropriately  
	SetCommandDescriptorBlock (	request,
								kSCSICmd_WRITE_AND_VERIFY_10,
								( WRPROTECT << 5 ) | ( DPO << 4 ) | ( BYTCHK << 1 ),
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8  ) & 0xFF,
								  LOGICAL_BLOCK_ADDRESS			& 0xFF,
								( TRANSFER_LENGTH >> 24 ) & 0xFF,
								( TRANSFER_LENGTH >> 16 ) & 0xFF,
								( TRANSFER_LENGTH >> 8 ) & 0xFF,
								TRANSFER_LENGTH & 0xFF,
								GROUP_NUMBER,
								CONTROL );
	
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_FromInitiatorToTarget );
	SetTimeoutDuration ( request, 0 );
	SetDataBuffer ( request, dataBuffer );
	SetRequestedDataTransferCount ( request,  requestedByteCount );
	
	status = true;
	
	
ErrorExit:
	
	
	return status;

}

//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ WRITE_AND_VERIFY_16 - Builds a WRITE_AND_VERIFY_12 command.	[PROTECTED]
//  Defined in SBC-2 section 5.34
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::WRITE_AND_VERIFY_16 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						UInt32						blockSize,
						SCSICmdField3Bit			WRPROTECT,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			BYTCHK,
						SCSICmdField8Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField4Byte 			TRANSFER_LENGTH,
						SCSICmdField5Bit			GROUP_NUMBER,
						SCSICmdField1Byte 			CONTROL )
{

	bool		status 				= false;
	UInt64 		requestedByteCount	= 0;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );
	
	// Check the validity of the media
	require_nonzero ( blockSize, ErrorExit );
	
	requestedByteCount = TRANSFER_LENGTH * blockSize;

	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( WRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
	require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( BYTCHK, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask8Byte ), ErrorExit );
	require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
	require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	require ( IsMemoryDescriptorValid ( dataBuffer, requestedByteCount ), ErrorExit );

	// This is a 12-Byte command, fill out the cdb appropriately  
	SetCommandDescriptorBlock (	request,
								kSCSICmd_WRITE_AND_VERIFY_16,
								( WRPROTECT << 5 ) | ( DPO << 4 ) | ( BYTCHK << 1 ),
								( LOGICAL_BLOCK_ADDRESS >> 56 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 48 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 40 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 32 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8  ) & 0xFF,
								  LOGICAL_BLOCK_ADDRESS			& 0xFF,
								( TRANSFER_LENGTH >> 24 ) & 0xFF,
								( TRANSFER_LENGTH >> 16 ) & 0xFF,
								( TRANSFER_LENGTH >> 8 ) & 0xFF,
								TRANSFER_LENGTH & 0xFF,
								GROUP_NUMBER,
								CONTROL );
	
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_FromInitiatorToTarget );
	SetTimeoutDuration ( request, 0 );
	SetDataBuffer ( request, dataBuffer );
	SetRequestedDataTransferCount ( request,  requestedByteCount );
	
	status = true;
	
	
ErrorExit:
	
	
	return status;

}

//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ WRITE_LONG - Builds a WRITE_LONG command.						[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::WRITE_LONG (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField1Bit 			RELADR,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField2Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->WRITE_LONG (
				scsiRequest,
				dataBuffer,
				RELADR,
				LOGICAL_BLOCK_ADDRESS,
				TRANSFER_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ WRITE_LONG_16 - Builds a WRITE_LONG_16 command.				[PROTECTED]
//  Defined in SBC-2 section 5.38
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::WRITE_LONG_16 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField8Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField2Byte 			TRANSFER_LENGTH,
						SCSICmdField1Bit			CORRCT,
						SCSICmdField1Byte 			CONTROL )
{

	bool		status 		= false;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );

	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask8Byte ), ErrorExit );
	require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
	require ( IsParameterValid ( CORRCT, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	require ( IsMemoryDescriptorValid ( dataBuffer, TRANSFER_LENGTH ), ErrorExit );
	
	// This is a 16-Byte command, fill out the cdb appropriately  
	SetCommandDescriptorBlock (	request,
								kSCSICmd_WRITE_LONG,
								0x11, // Need to make a constant later, see SBC-2 spec section 5.38
								( LOGICAL_BLOCK_ADDRESS >> 56 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 48 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 40 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 32 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8  ) & 0xFF,
								  LOGICAL_BLOCK_ADDRESS			& 0xFF,
								0x00,
								0x00,
								( TRANSFER_LENGTH >> 8 )		& 0xFF,
								  TRANSFER_LENGTH				& 0xFF,
								CORRCT,
								CONTROL );
	
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_FromInitiatorToTarget );
	SetTimeoutDuration ( request, 0 );
	SetDataBuffer ( request, dataBuffer );
	SetRequestedDataTransferCount ( request,  TRANSFER_LENGTH );

	status = true;
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ WRITE_SAME - Builds a WRITE_SAME command.						[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::WRITE_SAME (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField1Bit 			PBDATA,
						SCSICmdField1Bit 			LBDATA,
						SCSICmdField1Bit 			RELADR,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField2Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->WRITE_SAME (
				scsiRequest,
				dataBuffer,
				PBDATA,
				LBDATA,
				RELADR,
				LOGICAL_BLOCK_ADDRESS,
				TRANSFER_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ WRITE_SAME - Builds a WRITE_SAME command.						[PROTECTED]
//  Defined in SBC-2 section 5.39
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::WRITE_SAME (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField3Bit			WRPROTECT,
						SCSICmdField1Bit 			PBDATA,
						SCSICmdField1Bit 			LBDATA,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField5Bit			GROUP_NUMBER,
						SCSICmdField2Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{

	bool		status 		= false;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );
	
	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( WRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
	require ( IsParameterValid ( PBDATA, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LBDATA, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	require ( IsMemoryDescriptorValid ( dataBuffer, TRANSFER_LENGTH ), ErrorExit );
	
	// Can't have PBDATA and LBDATA set in same command
	require ( ( PBDATA == !LBDATA ), ErrorExit );
	
	// This is a 10-Byte command, fill out the cdb appropriately  
	SetCommandDescriptorBlock (	request,
								kSCSICmd_WRITE_SAME,
								( WRPROTECT << 5 ) | ( PBDATA << 2 ) | ( LBDATA << 1 ),
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8  ) & 0xFF,
								  LOGICAL_BLOCK_ADDRESS			& 0xFF,
								GROUP_NUMBER,
								( TRANSFER_LENGTH >> 8 )		& 0xFF,
								  TRANSFER_LENGTH				& 0xFF,
								CONTROL );
	
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_FromInitiatorToTarget );
	SetTimeoutDuration ( request, 0 );
	SetDataBuffer ( request, dataBuffer );
	SetRequestedDataTransferCount ( request,  TRANSFER_LENGTH );
	
	status = true;
	
	
ErrorExit:
	
	
	return status;
	

}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ WRITE_SAME_16 - Builds a WRITE_SAME_16 command.				[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::WRITE_SAME_16 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField3Bit			WRPROTECT,
						SCSICmdField1Bit			PBDATA,
						SCSICmdField1Bit			LBDATA,
						SCSICmdField8Byte			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField4Byte			TRANSFER_LENGTH,
						SCSICmdField5Bit			GROUP_NUMBER,
						SCSICmdField1Byte			CONTROL )
{

	bool		status 		= false;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );
	
	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( WRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
	require ( IsParameterValid ( PBDATA, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LBDATA, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask8Byte ), ErrorExit );
	require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	require ( IsMemoryDescriptorValid ( dataBuffer, TRANSFER_LENGTH ), ErrorExit );
	
	// Can't have PBDATA and LBDATA set in same command
	require ( ( PBDATA == !LBDATA ), ErrorExit );
	
	// This is a 16-Byte command, fill out the cdb appropriately
	SetCommandDescriptorBlock ( request,
								kSCSICmd_WRITE_SAME_16,
								( WRPROTECT << 5 ) | ( PBDATA << 2 ) | ( LBDATA << 1 ),
								( LOGICAL_BLOCK_ADDRESS >> 56 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 48 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 40 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 32 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF,
								LOGICAL_BLOCK_ADDRESS & 0xFF,
								( TRANSFER_LENGTH >> 24 ) & 0xFF,
								( TRANSFER_LENGTH >> 16 ) & 0xFF,
								( TRANSFER_LENGTH >> 8 ) & 0xFF,
								TRANSFER_LENGTH & 0xFF,
								GROUP_NUMBER,
								CONTROL );

	SetDataTransferDirection ( 	request, kSCSIDataTransfer_FromInitiatorToTarget );
	SetTimeoutDuration ( request, 0 );
	SetDataBuffer ( request, dataBuffer );
	SetRequestedDataTransferCount ( request,  TRANSFER_LENGTH );
		
	status = true;
	
	
ErrorExit:

	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ XDREAD - Builds a XDREAD command.								[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::XDREAD (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField2Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->XDREAD (
				scsiRequest,
				dataBuffer,
				LOGICAL_BLOCK_ADDRESS,
				TRANSFER_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ XDREAD - Builds a XDREAD command.								[PROTECTED]
//  Defined in SBC-2 section 5.42.
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::XDREAD (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField1Bit			XORPINFO,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField5Bit			GROUP_NUMBER,
						SCSICmdField2Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{

	bool		status 		= false;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );

	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( XORPINFO, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
	require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	require ( IsMemoryDescriptorValid ( dataBuffer, TRANSFER_LENGTH ), ErrorExit );
	
	// This is a 10-Byte command, fill out the cdb appropriately  
	SetCommandDescriptorBlock (	request,
								kSCSICmd_XDREAD,
								XORPINFO,
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8  ) & 0xFF,
								  LOGICAL_BLOCK_ADDRESS			& 0xFF,
								GROUP_NUMBER,
								( TRANSFER_LENGTH >> 8 )		& 0xFF,
								  TRANSFER_LENGTH				& 0xFF,
								CONTROL );
	
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_FromInitiatorToTarget );
	SetTimeoutDuration ( request, 0 );
	SetDataBuffer ( request, dataBuffer );
	SetRequestedDataTransferCount ( request,  TRANSFER_LENGTH );
	
	status = true;
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ XDWRITE - Builds a XDWRITE command.							[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::XDWRITE (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			FUA,
						SCSICmdField1Bit 			DISABLE_WRITE,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField2Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->XDWRITE (
				scsiRequest,
				dataBuffer,
				DPO,
				FUA,
				DISABLE_WRITE,
				LOGICAL_BLOCK_ADDRESS,
				TRANSFER_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ XDWRITE - Builds a XDWRITE command.							[PROTECTED]
//  Defined in SBC-2 section 5.43
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::XDWRITE (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField3Bit			WRPROTECT,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			FUA,
						SCSICmdField1Bit 			DISABLE_WRITE,
						SCSICmdField1Bit			FUA_NV,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField5Bit			GROUP_NUMBER,
						SCSICmdField2Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{

	bool		status 		= false;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );

	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( WRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
	require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( DISABLE_WRITE, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( FUA_NV, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
	require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	require ( IsMemoryDescriptorValid ( dataBuffer, TRANSFER_LENGTH ), ErrorExit );
	
	// This is a 10-Byte command, fill out the cdb appropriately  
	SetCommandDescriptorBlock (	request,
								kSCSICmd_XDWRITE,
								( WRPROTECT << 5 ) | ( DPO << 4 ) | ( FUA << 3 ) | ( DISABLE_WRITE << 2 ) | ( FUA_NV << 1 ),
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8  ) & 0xFF,
								  LOGICAL_BLOCK_ADDRESS			& 0xFF,
								GROUP_NUMBER,
								( TRANSFER_LENGTH >> 8 )		& 0xFF,
								  TRANSFER_LENGTH				& 0xFF,
								CONTROL );
	
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_FromInitiatorToTarget );
	SetTimeoutDuration ( request, 0 );
	SetDataBuffer ( request, dataBuffer );
	SetRequestedDataTransferCount ( request,  TRANSFER_LENGTH );
	
	status = true;
	
	
ErrorExit:
	
	
	return status;
	

}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ XDWRITE_EXTENDED - Builds a XDWRITE_EXTENDED command.			[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::XDWRITE_EXTENDED (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField1Bit 			TABLE_ADDRESS,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			FUA,
						SCSICmdField1Bit 			DISABLE_WRITE,
						SCSICmdField2Bit 			PORT_CONTROL,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField4Byte 			SECONDARY_BLOCK_ADDRESS,
						SCSICmdField4Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			SECONDARY_ADDRESS,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->XDWRITE_EXTENDED (
				scsiRequest,
				dataBuffer,
				TABLE_ADDRESS,
				DPO,
				FUA,
				DISABLE_WRITE,
				PORT_CONTROL,
				LOGICAL_BLOCK_ADDRESS,
				SECONDARY_BLOCK_ADDRESS,
				TRANSFER_LENGTH,
				SECONDARY_ADDRESS,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}


//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ XDWRITEREAD_10 - Builds a XDWRITEREAD_10 command.				[PROTECTED]
//  Defined in SBC-2 section 5.46
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::XDWRITEREAD_10 (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField3Bit			WRPROTECT,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			FUA,
						SCSICmdField1Bit 			DISABLE_WRITE,
						SCSICmdField1Bit 			FUA_NV,
						SCSICmdField1Bit 			XORPINFO,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField5Bit			GROUP_NUMBER,
						SCSICmdField2Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{

	bool		status 		= false;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );

	// Do the pre-flight check on the passed in parameters
	require ( IsParameterValid ( WRPROTECT, kSCSICmdFieldMask3Bit ), ErrorExit );
	require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( DISABLE_WRITE, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( FUA_NV, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( XORPINFO, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
	require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	require ( IsMemoryDescriptorValid ( dataBuffer, TRANSFER_LENGTH ), ErrorExit );
	
	// This is a 10-Byte command, fill out the cdb appropriately  
	SetCommandDescriptorBlock (	request,
								kSCSICmd_XDWRITE,
								( WRPROTECT << 5 ) | ( DPO << 4 ) | ( FUA << 3 ) | ( DISABLE_WRITE << 2 ) | ( FUA_NV << 1 ) | XORPINFO,
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8  ) & 0xFF,
								  LOGICAL_BLOCK_ADDRESS			& 0xFF,
								GROUP_NUMBER,
								( TRANSFER_LENGTH >> 8 )		& 0xFF,
								  TRANSFER_LENGTH				& 0xFF,
								CONTROL );
	
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_FromInitiatorToTarget );
	SetTimeoutDuration ( request, 0 );
	SetDataBuffer ( request, dataBuffer );
	SetRequestedDataTransferCount ( request,  TRANSFER_LENGTH );
	
	status = true;
	
	
ErrorExit:
	
	
	return status;
		
}

//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ XPWRITE - Builds a XPWRITE command.							[PROTECTED]
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool
IOSCSIBlockCommandsDevice::XPWRITE (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			FUA,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField2Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{
	
	SCSITask *	scsiRequest	= NULL;
	bool		status 		= false;
	
	scsiRequest = OSDynamicCast ( SCSITask, request );
	require_nonzero ( scsiRequest, ErrorExit );
	require ( scsiRequest->ResetForNewTask ( ), ErrorExit );
	
	status = GetSCSIBlockCommandObject ( )->XPWRITE (
				scsiRequest,
				dataBuffer,
				DPO,
				FUA,
				LOGICAL_BLOCK_ADDRESS,
				TRANSFER_LENGTH,
				CONTROL );
	
	
ErrorExit:
	
	
	return status;
	
}

//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ
//	₯ XPWRITE - Builds a XPWRITE command.							[PROTECTED]
//  Defined in SBC-2 section 5.48
//ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ

bool 
IOSCSIBlockCommandsDevice::XPWRITE (
						SCSITaskIdentifier			request,
						IOMemoryDescriptor *		dataBuffer,
						SCSICmdField1Bit 			DPO,
						SCSICmdField1Bit 			FUA,
						SCSICmdField1Bit 			FUA_NV,
						SCSICmdField1Bit 			XORPINFO,
						SCSICmdField4Byte 			LOGICAL_BLOCK_ADDRESS,
						SCSICmdField5Bit			GROUP_NUMBER,
						SCSICmdField2Byte 			TRANSFER_LENGTH,
						SCSICmdField1Byte 			CONTROL )
{

	bool		status 		= false;
	
	require_nonzero ( request, ErrorExit );
	require ( ResetForNewTask ( request ), ErrorExit );

	require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( FUA_NV, kSCSICmdFieldMask1Bit ), ErrorExit );
	require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit );
	require ( IsParameterValid ( GROUP_NUMBER, kSCSICmdFieldMask5Bit ), ErrorExit );
	require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit );
	require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit );
	
	// This is a 10-Byte command, fill out the cdb appropriately  
	SetCommandDescriptorBlock (	request,
								kSCSICmd_XPWRITE,
								( DPO << 4 ) | ( FUA << 3 ) | (FUA_NV << 1) | XORPINFO,
								( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF,
								( LOGICAL_BLOCK_ADDRESS >> 8  ) & 0xFF,
								  LOGICAL_BLOCK_ADDRESS 		& 0xFF,
								GROUP_NUMBER,
								( TRANSFER_LENGTH >> 8 ) & 0xFF,
								  TRANSFER_LENGTH		 & 0xFF,
								CONTROL );
	
	SetDataTransferDirection ( 	request, kSCSIDataTransfer_FromInitiatorToTarget );
	SetTimeoutDuration ( request, 0 );
	SetDataBuffer ( request, dataBuffer );
	SetRequestedDataTransferCount ( request,  TRANSFER_LENGTH );
	
	status = true;
	
	
ErrorExit:
	
	
	return status;
	
}