/** * @brief This method performs all of the translation required for a * SCSI VERIFY 16 byte CDB. * This includes: * - logical block address translation * - transfer length (sector count) translation * - translation items common to all VERIFY CDB sizes. * For more information on the parameters passed to this method, * please reference sati_translate_command(). * * @return Indicate if the command translation was successful. * For more information on return values please reference * sati_move_set_sector_count(), sati_verify_translate_command() */ SATI_STATUS sati_verify_16_translate_command( SATI_TRANSLATOR_SEQUENCE_T * sequence, void * scsi_io, void * ata_io ) { SATI_STATUS status; U8 * cdb = sati_cb_get_cdb_address(scsi_io); U32 sector_count = (sati_get_cdb_byte(cdb, 10) << 24) | (sati_get_cdb_byte(cdb, 11) << 16) | (sati_get_cdb_byte(cdb, 12) << 8) | (sati_get_cdb_byte(cdb, 13)); if(sati_device_state_stopped(sequence, scsi_io)) { return SATI_FAILURE_CHECK_RESPONSE_DATA; } else { sequence->type = SATI_SEQUENCE_VERIFY_16; // Fill in the Logical Block Address field. status = sati_move_translate_64_bit_lba(sequence, scsi_io, ata_io); if (status != SATI_SUCCESS) return status; // Fill in the Sector Count fields. status = sati_move_set_sector_count(sequence,scsi_io,ata_io,sector_count,0); if (status != SATI_SUCCESS) return status; return sati_verify_translate_command(sequence, scsi_io, ata_io); } }
/** * @brief This method will translate the SCSI read 16 command into a * corresponding ATA read command. Depending upon the capabilities * supported by the target different ATA commands can be selected. * It ensures that all translation required for this command is * performed successfully. * For more information on the parameters passed to this method, * please reference sati_translate_command(). * * @return Indicate if the command translation succeeded. * @see sati_read_large_translate_command(), sati_move_translate_64_bit_lba() * for additional return values. */ SATI_STATUS sati_read_16_translate_command( SATI_TRANSLATOR_SEQUENCE_T * sequence, void * scsi_io, void * ata_io ) { SATI_STATUS status; U8 device_head = 0; U8 * cdb = sati_cb_get_cdb_address(scsi_io); U32 sector_count = (sati_get_cdb_byte(cdb, 10) << 24) | (sati_get_cdb_byte(cdb, 11) << 16) | (sati_get_cdb_byte(cdb, 12) << 8) | (sati_get_cdb_byte(cdb, 13)); if(sati_device_state_stopped(sequence, scsi_io)) { return SATI_FAILURE_CHECK_RESPONSE_DATA; } else { sequence->type = SATI_SEQUENCE_READ_16; // Translate the sector count, write command register, and check various // other parts of the CDB. status = sati_read_large_translate_command( sequence, scsi_io, ata_io, sector_count, &device_head ); // Attempt to translate the 64-bit LBA field from the SCSI request // into the 48-bits of LBA in the ATA register FIS. if (status == SATI_SUCCESS) { sati_move_translate_command(sequence, scsi_io, ata_io, device_head); status = sati_move_translate_64_bit_lba(sequence, scsi_io, ata_io); } return status; } }
/** * @brief This method will translate the write long 10 & 16 SCSI commands into * ATA write uncorrectable commands. For more information on the * parameters passed to this method, please reference * sati_translate_command(). * * @return Indicate if the command translation succeeded. * @retval SCI_SUCCESS This is returned if the command translation was * successful. * @retval SATI_FAILURE_CHECK_RESPONSE_DATA is returned if there was * a problem with the translation of write long. * */ SATI_STATUS sati_write_long_translate_command( SATI_TRANSLATOR_SEQUENCE_T * sequence, void * scsi_io, void * ata_io ) { U8 * cdb = sati_cb_get_cdb_address(scsi_io); SATI_STATUS status = SATI_FAILURE; U16 byte_transfer_length; U8 device_head = 0; if((sequence->device->capabilities & SATI_DEVICE_CAP_WRITE_UNCORRECTABLE_ENABLE) == 0) { sati_scsi_sense_data_construct( sequence, scsi_io, SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INVALID_COMMAND_OPERATION_CODE, SCSI_ASCQ_INVALID_COMMAND_OPERATION_CODE ); return SATI_FAILURE_CHECK_RESPONSE_DATA; } //Write Long 10 if(sati_get_cdb_byte(cdb, 0) == SCSI_WRITE_LONG_10) { byte_transfer_length = (sati_get_cdb_byte(cdb, 7) << 8) | (sati_get_cdb_byte(cdb, 8)); sati_move_translate_32_bit_lba(sequence, scsi_io, ata_io); } else //Write Long 16 { byte_transfer_length = (sati_get_cdb_byte(cdb, 12) << 8) | (sati_get_cdb_byte(cdb, 13)); status = sati_move_translate_64_bit_lba(sequence, scsi_io, ata_io); if( status == SATI_FAILURE_CHECK_RESPONSE_DATA) { return status; } } sati_move_translate_command(sequence, scsi_io, ata_io, device_head); if( byte_transfer_length != 0 ) { sati_scsi_sense_data_construct( sequence, scsi_io, SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INVALID_FIELD_IN_CDB, SCSI_ASCQ_INVALID_FIELD_IN_CDB ); return SATI_FAILURE_CHECK_RESPONSE_DATA; } switch(SATI_WRITE_LONG_GET_COR_WR_PB_BITS(cdb)) { case WR_UNCOR_BIT : if( (sequence->device->capabilities & SATI_DEVICE_CAP_MULTIPLE_SECTORS_PER_PHYSCIAL_SECTOR) != 0 ) { sati_scsi_sense_data_construct( sequence, scsi_io, SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INVALID_FIELD_IN_CDB, SCSI_ASCQ_INVALID_FIELD_IN_CDB ); return SATI_FAILURE_CHECK_RESPONSE_DATA; } else { sati_ata_write_uncorrectable_construct( ata_io, sequence, ATA_WRITE_UNCORRECTABLE_PSUEDO ); sequence->type = SATI_SEQUENCE_WRITE_LONG; status = SATI_SUCCESS; } break; case WR_UNCOR_PBLOCK_BIT : sati_ata_write_uncorrectable_construct( ata_io, sequence, ATA_WRITE_UNCORRECTABLE_PSUEDO ); sequence->type = SATI_SEQUENCE_WRITE_LONG; status = SATI_SUCCESS; break; case COR_DIS_WR_UNCORR_BIT : sati_ata_write_uncorrectable_construct( ata_io, sequence, ATA_WRITE_UNCORRECTABLE_FLAGGED ); sequence->type = SATI_SEQUENCE_WRITE_LONG; status = SATI_SUCCESS; break; default : sati_scsi_sense_data_construct( sequence, scsi_io, SCSI_STATUS_CHECK_CONDITION, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INVALID_FIELD_IN_CDB, SCSI_ASCQ_INVALID_FIELD_IN_CDB ); return SATI_FAILURE_CHECK_RESPONSE_DATA; break; } return status; }