/* * Copyright (c) 1998-2002 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. * * 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 //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // Libkern includes #include // SCSI Architecture Model Family includes #include #include "SCSIBlockCommands.h" //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // Macros //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ #define DEBUG 0 #define DEBUG_ASSERT_COMPONENT_NAME_STRING "SBC Command Set" #if DEBUG #define SCSI_SBC_COMMANDS_DEBUGGING_LEVEL 0 #endif #include "IOSCSIArchitectureModelFamilyDebugging.h" #if ( SCSI_SBC_COMMANDS_DEBUGGING_LEVEL >= 1 ) #define PANIC_NOW(x) IOPanic x #else #define PANIC_NOW(x) #endif #if ( SCSI_SBC_COMMANDS_DEBUGGING_LEVEL >= 2 ) #define ERROR_LOG(x) IOLog x #else #define ERROR_LOG(x) #endif #if ( SCSI_SBC_COMMANDS_DEBUGGING_LEVEL >= 3 ) #define STATUS_LOG(x) IOLog x #else #define STATUS_LOG(x) #endif #define super SCSIPrimaryCommands OSDefineMetaClassAndStructors ( SCSIBlockCommands, SCSIPrimaryCommands ); #if 0 #pragma mark - #pragma mark SBC Command Methods #pragma mark - #endif // SCSI Block Commands as defined in T10:990D SBC, Revision 8c, // dated 13 November 1997 //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::ERASE_10 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The ERASE(10) command as defined in section 6.2.1 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::ERASE_10 ( SCSITask * request, SCSICmdField1Bit ERA, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField2Byte TRANSFER_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::ERASE_10 called\n" ) ); require ( IsParameterValid ( ERA, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), 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_ERASE_10, ( ERA << 2 ) | RELADR, ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, 0x00, ( TRANSFER_LENGTH >> 8 ) & 0xFF, TRANSFER_LENGTH & 0xFF, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_NoDataTransfer ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::ERASE_12 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The ERASE(12) command as defined in section 6.2.2 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::ERASE_12 ( SCSITask * request, SCSICmdField1Bit ERA, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField4Byte TRANSFER_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::ERASE_12 called\n" ) ); require ( IsParameterValid ( ERA, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); // This is a 12-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_ERASE_12, ( ERA << 2 ) | RELADR, ( 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, 0x00, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_NoDataTransfer ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::FORMAT_UNIT // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The FORMAT_UNIT command as defined in section 6.1.1 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::FORMAT_UNIT ( SCSITask * request, IOMemoryDescriptor * dataBuffer, IOByteCount defectListSize, SCSICmdField1Bit FMTDATA, SCSICmdField1Bit CMPLST, SCSICmdField3Bit DEFECT_LIST_FORMAT, SCSICmdField1Byte VENDOR_SPECIFIC, SCSICmdField2Byte INTERLEAVE, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::FORMAT_UNIT called\n" ) ); // Do the pre-flight check on the passed in parameters 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 ( INTERLEAVE, kSCSICmdFieldMask2Byte ), 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 ( IsBufferAndCapacityValid ( dataBuffer, defectListSize ), ErrorExit ); } // This is a 6-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_FORMAT_UNIT, ( FMTDATA << 4 ) | ( CMPLST << 4 ) | DEFECT_LIST_FORMAT, VENDOR_SPECIFIC, ( INTERLEAVE >> 8 ) & 0xFF, INTERLEAVE & 0xFF, CONTROL ); if ( FMTDATA == 0 ) { // No DEFECT LIST is being sent to the device, so there // will be no data transfer for this request. SetDataTransferControl ( request, 0, kSCSIDataTransfer_NoDataTransfer ); } else { // The client has requested a DEFECT LIST be sent to the device // to be used with the format command SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromInitiatorToTarget, dataBuffer ); // -->Need defect list size } result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::LOCK_UNLOCK_CACHE // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The LOCK_UNLOCK_CACHE command as defined in section 6.1.2 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::LOCK_UNLOCK_CACHE ( SCSITask * request, SCSICmdField1Bit LOCK, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField2Byte NUMBER_OF_BLOCKS, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::LOCK_UNLOCK_CACHE called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( LOCK, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( RELADR, 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 ) | RELADR, ( 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 ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_NoDataTransfer ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::MEDIUM_SCAN // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The MEDIUM_SCAN command as defined in section 6.2.3 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::MEDIUM_SCAN ( SCSITask * request, IOMemoryDescriptor * dataBuffer, SCSICmdField1Bit WBS, SCSICmdField1Bit ASA, SCSICmdField1Bit RSD, SCSICmdField1Bit PRA, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField2Byte PARAMETER_LIST_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::MEDIUM_SCAN called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( WBS, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( ASA, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( RSD, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( PRA, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( PARAMETER_LIST_LENGTH, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, PARAMETER_LIST_LENGTH ), ErrorExit ); // This is a 10-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_MEDIUM_SCAN, ( WBS << 4 ) | ( ASA << 3 ) | ( RSD << 2 ) | ( PRA << 1 ) | RELADR, ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, 0x00, 0x00, PARAMETER_LIST_LENGTH, CONTROL ); if ( PARAMETER_LIST_LENGTH > 0 ) { SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromInitiatorToTarget, dataBuffer, PARAMETER_LIST_LENGTH ); } else { SetDataTransferControl ( request, 0, kSCSIDataTransfer_NoDataTransfer ); } result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::PREFETCH // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The PREFETCH command as defined in section 6.1.3 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::PREFETCH ( SCSITask * request, SCSICmdField1Bit IMMED, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField2Byte TRANSFER_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::PREFETCH called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( IMMED, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), 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 ) | RELADR, ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, 0x00, ( TRANSFER_LENGTH >> 8 ) & 0xFF, TRANSFER_LENGTH & 0xFF, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_NoDataTransfer ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::READ_6 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The READ(6) command as defined in section 6.1.4 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::READ_6 ( SCSITask * request, IOMemoryDescriptor * dataBuffer, UInt64 transferCount, SCSICmdField21Bit LOGICAL_BLOCK_ADDRESS, SCSICmdField1Byte TRANSFER_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::READ_6 called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask21Bit ), ErrorExit ); require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, transferCount ), ErrorExit ); // This is a 6-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_READ_6, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0x1F, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, TRANSFER_LENGTH, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromTargetToInitiator, dataBuffer, transferCount ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::READ_10 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The READ(10) command as defined in section 6.1.5 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::READ_10 ( SCSITask * request, IOMemoryDescriptor * dataBuffer, UInt64 transferCount, SCSICmdField1Bit DPO, SCSICmdField1Bit FUA, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField2Byte TRANSFER_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::READ_10 called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, transferCount ), ErrorExit ); // This is a 10-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_READ_10, ( DPO << 4 ) | ( FUA << 3 ) | RELADR, ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, 0x00, ( TRANSFER_LENGTH >> 8 ) & 0xFF, TRANSFER_LENGTH & 0xFF, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromTargetToInitiator, dataBuffer, transferCount ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::READ_12 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The READ(12) command as defined in section 6.2.4 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::READ_12 ( SCSITask * request, IOMemoryDescriptor * dataBuffer, UInt64 transferCount, SCSICmdField1Bit DPO, SCSICmdField1Bit FUA, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField4Byte TRANSFER_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::READ_12 called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, transferCount ), ErrorExit ); // This is a 12-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_READ_12, ( DPO << 4 ) | ( FUA << 3 ) | RELADR, ( 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, 0x00, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromTargetToInitiator, dataBuffer, transferCount ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::READ_CAPACITY // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The READ_CAPACITY command as defined in section 6.1.6 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::READ_CAPACITY ( SCSITask * request, IOMemoryDescriptor * dataBuffer, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField1Bit PMI, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::READ_CAPACITY called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( PMI, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, 8 ), ErrorExit ); // This is a 10-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_READ_CAPACITY, RELADR, ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, 0x00, 0x00, PMI, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromTargetToInitiator, dataBuffer, 8 ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::READ_DEFECT_DATA_10 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The READ_DEFECT_DATA(10) command as defined in section 6.1.7 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::READ_DEFECT_DATA_10 ( SCSITask * request, IOMemoryDescriptor * dataBuffer, SCSICmdField1Bit PLIST, SCSICmdField1Bit GLIST, SCSICmdField3Bit DEFECT_LIST_FORMAT, SCSICmdField2Byte ALLOCATION_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::READ_DEFECT_DATA_10 called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( PLIST, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( GLIST, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( DEFECT_LIST_FORMAT, kSCSICmdFieldMask3Bit ), ErrorExit ); require ( IsParameterValid ( ALLOCATION_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, ALLOCATION_LENGTH ), ErrorExit ); // This is a 10-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_READ_DEFECT_DATA_10, 0x00, ( PLIST << 4 ) | ( GLIST << 3 ) | DEFECT_LIST_FORMAT, 0x00, 0x00, 0x00, 0x00, ( ALLOCATION_LENGTH >> 8 ) & 0xFF, ALLOCATION_LENGTH & 0xFF, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromTargetToInitiator, dataBuffer, ALLOCATION_LENGTH ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::READ_DEFECT_DATA_12 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The READ_DEFECT_DATA(12) command as defined in section 6.2.5 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::READ_DEFECT_DATA_12 ( SCSITask * request, IOMemoryDescriptor * dataBuffer, SCSICmdField1Bit PLIST, SCSICmdField1Bit GLIST, SCSICmdField3Bit DEFECT_LIST_FORMAT, SCSICmdField4Byte ALLOCATION_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::READ_DEFECT_DATA_12 called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( PLIST, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( GLIST, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( DEFECT_LIST_FORMAT, kSCSICmdFieldMask3Bit ), ErrorExit ); require ( IsParameterValid ( ALLOCATION_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, ALLOCATION_LENGTH ), ErrorExit ); // This is a 10-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_READ_DEFECT_DATA_12, ( PLIST << 4 ) | ( GLIST << 3 ) | DEFECT_LIST_FORMAT, 0x00, 0x00, 0x00, 0x00, ( ALLOCATION_LENGTH >> 24 ) & 0xFF, ( ALLOCATION_LENGTH >> 16 ) & 0xFF, ( ALLOCATION_LENGTH >> 8 ) & 0xFF, ALLOCATION_LENGTH & 0xFF, 0x00, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromTargetToInitiator, dataBuffer, ALLOCATION_LENGTH ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::READ_GENERATION // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The READ_GENERATION command as defined in section 6.2.6 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::READ_GENERATION ( SCSITask * request, IOMemoryDescriptor * dataBuffer, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField1Byte ALLOCATION_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::READ_GENERATION called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( ALLOCATION_LENGTH, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, ALLOCATION_LENGTH ), ErrorExit ); // This is a 10-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_READ_GENERATION, RELADR, ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, 0x00, 0x00, ALLOCATION_LENGTH, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromTargetToInitiator, dataBuffer, ALLOCATION_LENGTH ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::READ_LONG // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The READ_LONG command as defined in section 6.1.8 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::READ_LONG ( SCSITask * request, IOMemoryDescriptor * dataBuffer, SCSICmdField1Bit CORRCT, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField2Byte BYTE_TRANSFER_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::READ_LONG called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( CORRCT, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( BYTE_TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, BYTE_TRANSFER_LENGTH ), ErrorExit ); // This is a 10-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_READ_LONG, ( CORRCT << 1 ) | RELADR, ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, 0x00, ( BYTE_TRANSFER_LENGTH >> 8 ) & 0xFF, BYTE_TRANSFER_LENGTH & 0xFF, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromTargetToInitiator, dataBuffer, BYTE_TRANSFER_LENGTH ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::READ_UPDATED_BLOCK_10 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The READ_UPDATED_BLOCK(10) command as defined in section 6.2.7 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::READ_UPDATED_BLOCK_10 ( SCSITask * request, IOMemoryDescriptor * dataBuffer, UInt32 transferCount, SCSICmdField1Bit DPO, SCSICmdField1Bit FUA, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField1Bit LATEST, SCSICmdField15Bit GENERATION_ADDRESS, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::READ_UPDATED_BLOCK_10 called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( LATEST, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( GENERATION_ADDRESS, kSCSICmdFieldMask5Bit ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, transferCount ), ErrorExit ); // This is a 10-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_READ_UPDATED_BLOCK_10, ( DPO << 4 ) | ( FUA << 3 ) | RELADR, ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, ( LATEST << 7 ) | ( ( GENERATION_ADDRESS >> 8 ) & 0xFF ), GENERATION_ADDRESS & 0xFF, 0x00, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromTargetToInitiator, dataBuffer, transferCount ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::REASSIGN_BLOCKS // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The REASSIGN_BLOCKS command as defined in section 6.1.9 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::REASSIGN_BLOCKS ( SCSITask * request, IOMemoryDescriptor * dataBuffer, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::REASSIGN_BLOCKS called\n" ) ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); // This is a 6-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_REASSIGN_BLOCKS, 0x00, 0x00, 0x00, 0x00, CONTROL ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::REBUILD // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The REBUILD command as defined in section 6.1.10 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::REBUILD ( SCSITask * 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 ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::REBUILD called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( INTDATA, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( PORT_CONTROL, kSCSICmdFieldMask2Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( REBUILD_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( PARAMETER_LIST_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, PARAMETER_LIST_LENGTH ), ErrorExit ); // This is a 16-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_REBUILD, ( DPO << 4 ) | ( FUA << 3 ) | ( INTDATA < 2 ) | PORT_CONTROL, ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, ( REBUILD_LENGTH >> 24 ) & 0xFF, ( REBUILD_LENGTH >> 16 ) & 0xFF, ( REBUILD_LENGTH >> 8 ) & 0xFF, REBUILD_LENGTH & 0xFF, ( PARAMETER_LIST_LENGTH >> 24 ) & 0xFF, ( PARAMETER_LIST_LENGTH >> 16 ) & 0xFF, ( PARAMETER_LIST_LENGTH >> 8 ) & 0xFF, PARAMETER_LIST_LENGTH & 0xFF, 0x00, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromInitiatorToTarget, dataBuffer, PARAMETER_LIST_LENGTH ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::REGENERATE // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The REGENERATE command as defined in section 6.1.11 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::REGENERATE ( SCSITask * request, IOMemoryDescriptor * dataBuffer, SCSICmdField1Bit DPO, SCSICmdField1Bit FUA, SCSICmdField1Bit INTDATA, SCSICmdField2Bit PORT_CONTROL, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField4Byte REGENERATE_LENGTH, SCSICmdField4Byte PARAMETER_LIST_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::REGENERATE called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( INTDATA, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( PORT_CONTROL, kSCSICmdFieldMask2Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( REGENERATE_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( PARAMETER_LIST_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, PARAMETER_LIST_LENGTH ), ErrorExit ); // This is a 16-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_REGENERATE, ( DPO << 4 ) | ( FUA << 3 ) | ( INTDATA < 2 ) | PORT_CONTROL, ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, ( REGENERATE_LENGTH >> 24 ) & 0xFF, ( REGENERATE_LENGTH >> 16 ) & 0xFF, ( REGENERATE_LENGTH >> 8 ) & 0xFF, REGENERATE_LENGTH & 0xFF, ( PARAMETER_LIST_LENGTH >> 24 ) & 0xFF, ( PARAMETER_LIST_LENGTH >> 16 ) & 0xFF, ( PARAMETER_LIST_LENGTH >> 8 ) & 0xFF, PARAMETER_LIST_LENGTH & 0xFF, 0x00, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromInitiatorToTarget, dataBuffer, PARAMETER_LIST_LENGTH ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::REZERO_UNIT // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // ₯₯₯ OBSOLETE ₯₯₯ // // The REZERO_UNIT command as defined in SCSI-2 section 9.2.13. // REZERO_UNIT is obsoleted by the SBC specification. // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::REZERO_UNIT ( SCSITask * request, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::REZERO_UNIT called\n" ) ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); // This is a 6-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_REZERO_UNIT, 0x00, 0x00, 0x00, 0x00, CONTROL ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::SEARCH_DATA_EQUAL_10 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // ₯₯₯ OBSOLETE ₯₯₯ // // The SEARCH_DATA_EQUAL(10) command as defined in SCSI-2, // section 9.2.14. // SEARCH_DATA_EQUAL(10) is obsoleted by the SBC specification. // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::SEARCH_DATA_EQUAL_10 ( SCSITask * request, IOMemoryDescriptor * dataBuffer, UInt32 transferCount, SCSICmdField1Bit INVERT, SCSICmdField1Bit SPNDAT, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField2Byte NUMBER_OF_BLOCKS_TO_SEARCH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::SEARCH_DATA_EQUAL_10 called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( INVERT, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( SPNDAT, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( NUMBER_OF_BLOCKS_TO_SEARCH, kSCSICmdFieldMask2Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, max ( transferCount, SEARCH_DATA_PARAMETER_LIST_MIN_LENGTH ) ), ErrorExit ); // This is a 10-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_SEARCH_DATA_EQUAL_10, ( INVERT << 4 ) | ( SPNDAT << 1 ) | RELADR, ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, 0x00, ( NUMBER_OF_BLOCKS_TO_SEARCH >> 8 ) & 0xFF, NUMBER_OF_BLOCKS_TO_SEARCH & 0xFF, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromInitiatorToTarget, dataBuffer, transferCount ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::SEARCH_DATA_HIGH_10 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // ₯₯₯ OBSOLETE ₯₯₯ // // The SEARCH_DATA_HIGH(10) command as defined in SCSI-2, // section 9.2.14. // SEARCH_DATA_HIGH(10) is obsoleted by the SBC specification. // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::SEARCH_DATA_HIGH_10 ( SCSITask * request, IOMemoryDescriptor * dataBuffer, UInt32 transferCount, SCSICmdField1Bit INVERT, SCSICmdField1Bit SPNDAT, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField2Byte NUMBER_OF_BLOCKS_TO_SEARCH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::SEARCH_DATA_HIGH_10 called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( INVERT, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( SPNDAT, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( NUMBER_OF_BLOCKS_TO_SEARCH, kSCSICmdFieldMask2Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, max ( transferCount, SEARCH_DATA_PARAMETER_LIST_MIN_LENGTH ) ), ErrorExit ); // This is a 10-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_SEARCH_DATA_HIGH_10, ( INVERT << 4 ) | ( SPNDAT << 1 ) | RELADR, ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, 0x00, ( NUMBER_OF_BLOCKS_TO_SEARCH >> 8 ) & 0xFF, NUMBER_OF_BLOCKS_TO_SEARCH & 0xFF, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromInitiatorToTarget, dataBuffer, transferCount ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::SEARCH_DATA_LOW_10 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // ₯₯₯ OBSOLETE ₯₯₯ // // The SEARCH_DATA_LOW(10) command as defined in SCSI-2, // section 9.2.14. // SEARCH_DATA_LOW(10) is obsoleted by the SBC specification. // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::SEARCH_DATA_LOW_10 ( SCSITask * request, IOMemoryDescriptor * dataBuffer, UInt32 transferCount, SCSICmdField1Bit INVERT, SCSICmdField1Bit SPNDAT, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField2Byte NUMBER_OF_BLOCKS_TO_SEARCH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::SEARCH_DATA_LOW_10 called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( INVERT, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( SPNDAT, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( NUMBER_OF_BLOCKS_TO_SEARCH, kSCSICmdFieldMask2Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, max ( transferCount, SEARCH_DATA_PARAMETER_LIST_MIN_LENGTH ) ), ErrorExit ); // This is a 10-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_SEARCH_DATA_LOW_10, ( INVERT << 4 ) | ( SPNDAT << 1 ) | RELADR, ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, 0x00, ( NUMBER_OF_BLOCKS_TO_SEARCH >> 8 ) & 0xFF, NUMBER_OF_BLOCKS_TO_SEARCH & 0xFF, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromInitiatorToTarget, dataBuffer, transferCount ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::SEEK_6 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // ₯₯₯ OBSOLETE ₯₯₯ // // The SEEK(6) command as defined in SCSI-2, section 9.2.15. // SEEK(6) is obsoleted by the SBC specification. // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::SEEK_6 ( SCSITask * request, SCSICmdField21Bit LOGICAL_BLOCK_ADDRESS, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::SEEK_6 called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask21Bit ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); // This is a 6-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_SEEK_6, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0x1F, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, 0x00, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_NoDataTransfer ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::SEEK_10 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The SEEK(10) command as defined in section 6.1.12 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::SEEK_10 ( SCSITask * request, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::SEEK_10 called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); // This is a 10-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_SEEK_10, 0x00, ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, 0x00, 0x00, 0x00, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_NoDataTransfer ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::SET_LIMITS_10 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The SET_LIMITS(10) command as defined in section 6.1.13 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::SET_LIMITS_10 ( SCSITask * request, SCSICmdField1Bit RDINH, SCSICmdField1Bit WRINH, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField2Byte NUMBER_OF_BLOCKS, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::SET_LIMITS_10 called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( RDINH, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( WRINH, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( NUMBER_OF_BLOCKS, kSCSICmdFieldMask2Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); // This is a 10-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_SET_LIMITS_10, ( RDINH << 1 ) | WRINH, ( 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 ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_NoDataTransfer ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::SET_LIMITS_12 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The SET_LIMITS(12) command as defined in section 6.2.8 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::SET_LIMITS_12 ( SCSITask * request, SCSICmdField1Bit RDINH, SCSICmdField1Bit WRINH, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField4Byte NUMBER_OF_BLOCKS, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::SET_LIMITS_12 called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( RDINH, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( WRINH, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( NUMBER_OF_BLOCKS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); // This is a 12-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_SET_LIMITS_12, ( RDINH << 1 ) | WRINH, ( 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 ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_NoDataTransfer ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::START_STOP_UNIT // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The START_STOP_UNIT command as defined in section 6.1.14 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::START_STOP_UNIT ( SCSITask * request, SCSICmdField1Bit IMMED, SCSICmdField4Bit POWER_CONDITIONS, SCSICmdField1Bit LOEJ, SCSICmdField1Bit START, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::START_STOP_UNIT called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( IMMED, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( POWER_CONDITIONS, kSCSICmdFieldMask4Bit ), ErrorExit ); require ( IsParameterValid ( LOEJ, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( START, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); // This is a 6-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_START_STOP_UNIT, IMMED, 0x00, 0x00, ( POWER_CONDITIONS << 4 ) | ( LOEJ << 1 ) | START, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_NoDataTransfer ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::SYNCHRONIZE_CACHE // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The SYNCHRONIZE_CACHE command as defined in section 6.1.15 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::SYNCHRONIZE_CACHE ( SCSITask * request, SCSICmdField1Bit IMMED, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField2Byte NUMBER_OF_BLOCKS, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::SYNCHRONIZE_CACHE called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( IMMED, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), 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, ( IMMED << 1 ) | RELADR, ( 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 ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_NoDataTransfer ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::UPDATE_BLOCK // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The UPDATE_BLOCK command as defined in section 6.2.9 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::UPDATE_BLOCK ( SCSITask * request, IOMemoryDescriptor * dataBuffer, UInt64 transferCount, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::UPDATE_BLOCK called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, transferCount ), ErrorExit ); // This is a 10-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_UPDATE_BLOCK, RELADR, ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, 0x00, 0x00, 0x00, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromInitiatorToTarget, dataBuffer, transferCount ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::VERIFY_10 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The VERIFY(10) command as defined in sections 6.1.16 and 6.2.10 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::VERIFY_10 ( SCSITask * request, SCSICmdField1Bit DPO, SCSICmdField1Bit BLKVFY, SCSICmdField1Bit BYTCHK, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField2Byte VERIFICATION_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::VERIFY_10 called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( BLKVFY, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( BYTCHK, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), 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, ( DPO << 4 ) | ( BLKVFY << 2 ) | ( BYTCHK << 1 ) | RELADR, ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, 0x00, ( VERIFICATION_LENGTH >> 8 ) & 0xFF, VERIFICATION_LENGTH & 0xFF, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_NoDataTransfer ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::VERIFY_12 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The VERIFY(12) command as defined in section 6.2.11 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::VERIFY_12 ( SCSITask * request, SCSICmdField1Bit DPO, SCSICmdField1Bit BLKVFY, SCSICmdField1Bit BYTCHK, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField4Byte VERIFICATION_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::VERIFY_12 called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( BLKVFY, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( BYTCHK, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), 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, ( DPO << 4 ) | ( BLKVFY << 2 ) | ( BYTCHK << 1 ) | RELADR, ( 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 ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_NoDataTransfer ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::WRITE_6 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The WRITE(6) command as defined in section 6.1.17 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::WRITE_6 ( SCSITask * request, IOMemoryDescriptor * dataBuffer, UInt64 transferCount, SCSICmdField21Bit LOGICAL_BLOCK_ADDRESS, SCSICmdField1Byte TRANSFER_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::WRITE_6 called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask2Byte ), ErrorExit ); require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, transferCount ), ErrorExit ); // This is a 6-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_WRITE_6, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, TRANSFER_LENGTH, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromInitiatorToTarget, dataBuffer, transferCount ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::WRITE_10 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The WRITE(10) command as defined in sections 6.1.18 and 6.2.12 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::WRITE_10 ( SCSITask * request, IOMemoryDescriptor * dataBuffer, UInt64 transferCount, SCSICmdField1Bit DPO, SCSICmdField1Bit FUA, SCSICmdField1Bit EBP, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField2Byte TRANSFER_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::WRITE_10 called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, transferCount ), ErrorExit ); // This is a 10-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_WRITE_10, ( DPO << 4 ) | ( FUA << 3 ) | RELADR, ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, 0x00, ( TRANSFER_LENGTH >> 8 ) & 0xFF, TRANSFER_LENGTH & 0xFF, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromInitiatorToTarget, dataBuffer, transferCount ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::WRITE_12 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The WRITE(12) command as defined in section 6.2.13 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::WRITE_12 ( SCSITask * request, IOMemoryDescriptor * dataBuffer, UInt64 transferCount, SCSICmdField1Bit DPO, SCSICmdField1Bit FUA, SCSICmdField1Bit EBP, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField4Byte TRANSFER_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::WRITE_12 called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( EBP, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, transferCount ), ErrorExit ); // This is a 12-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_WRITE_12, ( DPO << 4 ) | ( FUA << 3 ) | ( EBP << 2 ) | RELADR, ( 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, 0x00, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromInitiatorToTarget, dataBuffer, transferCount ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::WRITE_AND_VERIFY_10 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The WRITE_AND_VERIFY(10) command as defined in sections 6.1.19 // and 6.2.14 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::WRITE_AND_VERIFY_10 ( SCSITask * request, IOMemoryDescriptor * dataBuffer, UInt64 transferCount, SCSICmdField1Bit DPO, SCSICmdField1Bit EBP, SCSICmdField1Bit BYTCHK, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField2Byte TRANSFER_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::WRITE_AND_VERIFY_10 called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( EBP, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( BYTCHK, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, transferCount ), ErrorExit ); // This is a 10-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_WRITE_AND_VERIFY_10, ( DPO << 4 ) | ( EBP << 2 ) | ( BYTCHK << 1 ) | RELADR, ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, 0x00, ( TRANSFER_LENGTH >> 8 ) & 0xFF, TRANSFER_LENGTH & 0xFF, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromInitiatorToTarget, dataBuffer, transferCount ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::WRITE_AND_VERIFY_12 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The WRITE_AND_VERIFY(12) command as defined in sections 6.2.15 // and 6.2.14 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::WRITE_AND_VERIFY_12 ( SCSITask * request, IOMemoryDescriptor * dataBuffer, UInt64 transferCount, SCSICmdField1Bit DPO, SCSICmdField1Bit EBP, SCSICmdField1Bit BYTCHK, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField4Byte TRANSFER_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::WRITE_AND_VERIFY_12 called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( EBP, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( BYTCHK, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, transferCount ), ErrorExit ); // This is a 12-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_WRITE_AND_VERIFY_12, ( DPO << 4 ) | ( EBP << 2 ) | ( BYTCHK << 1 ) | RELADR, ( 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, 0x00, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromInitiatorToTarget, dataBuffer, transferCount ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::WRITE_LONG // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The WRITE_LONG command as defined in section 6.1.20 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::WRITE_LONG ( SCSITask * request, IOMemoryDescriptor * dataBuffer, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField2Byte TRANSFER_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::WRITE_LONG called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, TRANSFER_LENGTH ), ErrorExit ); // This is a 10-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_WRITE_LONG, RELADR, ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, 0x00, ( TRANSFER_LENGTH >> 8 ) & 0xFF, TRANSFER_LENGTH & 0xFF, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromInitiatorToTarget, dataBuffer, TRANSFER_LENGTH ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::WRITE_SAME // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The WRITE_SAME command as defined in section 6.1.21 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::WRITE_SAME ( SCSITask * request, IOMemoryDescriptor * dataBuffer, SCSICmdField1Bit PBDATA, SCSICmdField1Bit LBDATA, SCSICmdField1Bit RELADR, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField2Byte TRANSFER_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::WRITE_SAME called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( PBDATA, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LBDATA, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( RELADR, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( 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, ( PBDATA << 2 ) | ( LBDATA << 1 ) | RELADR, ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, 0x00, ( TRANSFER_LENGTH >> 8 ) & 0xFF, TRANSFER_LENGTH & 0xFF, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromInitiatorToTarget, dataBuffer, TRANSFER_LENGTH ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::XDREAD // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The XDREAD command as defined in section 6.1.22 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::XDREAD ( SCSITask * request, IOMemoryDescriptor * dataBuffer, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField2Byte TRANSFER_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::XDREAD called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, TRANSFER_LENGTH ), ErrorExit ); // This is a 10-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_XDREAD, 0x00, ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, 0x00, ( TRANSFER_LENGTH >> 8 ) & 0xFF, TRANSFER_LENGTH & 0xFF, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromInitiatorToTarget, dataBuffer, TRANSFER_LENGTH ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::XDWRITE // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The XDWRITE command as defined in section 6.1.23 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::XDWRITE ( SCSITask * request, IOMemoryDescriptor * dataBuffer, SCSICmdField1Bit DPO, SCSICmdField1Bit FUA, SCSICmdField1Bit DISABLE_WRITE, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField2Byte TRANSFER_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::XDWRITE called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( DISABLE_WRITE, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask2Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, TRANSFER_LENGTH ), ErrorExit ); // This is a 10-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_XDWRITE, ( DPO << 4 ) | ( FUA << 3 ) | ( DISABLE_WRITE << 2 ), ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, 0x00, ( TRANSFER_LENGTH >> 8 ) & 0xFF, TRANSFER_LENGTH & 0xFF, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromInitiatorToTarget, dataBuffer, TRANSFER_LENGTH ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::XDWRITE_EXTENDED // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The XDWRITE_EXTENDED command as defined in section 6.1.24 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::XDWRITE_EXTENDED ( SCSITask * 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 ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::XDWRITE_EXTENDED called\n" ) ); // Do the pre-flight check on the passed in parameters require ( IsParameterValid ( TABLE_ADDRESS, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( DISABLE_WRITE, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( PORT_CONTROL, kSCSICmdFieldMask2Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( SECONDARY_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( TRANSFER_LENGTH, kSCSICmdFieldMask4Byte ), ErrorExit ); require ( IsParameterValid ( SECONDARY_ADDRESS, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsParameterValid ( CONTROL, kSCSICmdFieldMask1Byte ), ErrorExit ); require ( IsBufferAndCapacityValid ( dataBuffer, TRANSFER_LENGTH ), ErrorExit ); // This is a 16-Byte command, fill out the cdb appropriately SetCommandDescriptorBlock ( request, kSCSICmd_XDWRITE_EXTENDED, ( TABLE_ADDRESS << 7 ) | ( DPO << 4 ) | ( FUA << 3 ) | ( DISABLE_WRITE < 2 ) | PORT_CONTROL, ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, ( SECONDARY_BLOCK_ADDRESS >> 24 ) & 0xFF, ( SECONDARY_BLOCK_ADDRESS >> 16 ) & 0xFF, ( SECONDARY_BLOCK_ADDRESS >> 8 ) & 0xFF, SECONDARY_BLOCK_ADDRESS & 0xFF, ( TRANSFER_LENGTH >> 24 ) & 0xFF, ( TRANSFER_LENGTH >> 16 ) & 0xFF, ( TRANSFER_LENGTH >> 8 ) & 0xFF, TRANSFER_LENGTH & 0xFF, SECONDARY_ADDRESS, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromInitiatorToTarget, dataBuffer, TRANSFER_LENGTH ); result = true; ErrorExit: return result; } //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::XPWRITE // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // The XPWRITE command as defined in section 6.1.25 // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ bool SCSIBlockCommands::XPWRITE ( SCSITask * request, IOMemoryDescriptor * dataBuffer, SCSICmdField1Bit DPO, SCSICmdField1Bit FUA, SCSICmdField4Byte LOGICAL_BLOCK_ADDRESS, SCSICmdField2Byte TRANSFER_LENGTH, SCSICmdField1Byte CONTROL ) { bool result = false; STATUS_LOG ( ( "SCSIBlockCommands::XPWRITE called\n" ) ); require ( IsParameterValid ( DPO, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( FUA, kSCSICmdFieldMask1Bit ), ErrorExit ); require ( IsParameterValid ( LOGICAL_BLOCK_ADDRESS, kSCSICmdFieldMask4Byte ), 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 ), ( LOGICAL_BLOCK_ADDRESS >> 24 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 16 ) & 0xFF, ( LOGICAL_BLOCK_ADDRESS >> 8 ) & 0xFF, LOGICAL_BLOCK_ADDRESS & 0xFF, 0x00, ( TRANSFER_LENGTH >> 8 ) & 0xFF, TRANSFER_LENGTH & 0xFF, CONTROL ); SetDataTransferControl ( request, 0, kSCSIDataTransfer_FromInitiatorToTarget, dataBuffer, TRANSFER_LENGTH ); result = true; ErrorExit: return result; } #if 0 #pragma mark - #pragma mark ₯ Static Methods #pragma mark - #endif //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // SCSIBlockCommands::CreateSCSIBlockCommandObject // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ // // Factory method for getting an instance of the command builder // //ΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡΡ SCSIBlockCommands * SCSIBlockCommands::CreateSCSIBlockCommandObject ( void ) { return OSTypeAlloc ( SCSIBlockCommands ); }