sati_read.c revision 230557
1230557Sjimharris/*- 2230557Sjimharris * This file is provided under a dual BSD/GPLv2 license. When using or 3230557Sjimharris * redistributing this file, you may do so under either license. 4230557Sjimharris * 5230557Sjimharris * GPL LICENSE SUMMARY 6230557Sjimharris * 7230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 8230557Sjimharris * 9230557Sjimharris * This program is free software; you can redistribute it and/or modify 10230557Sjimharris * it under the terms of version 2 of the GNU General Public License as 11230557Sjimharris * published by the Free Software Foundation. 12230557Sjimharris * 13230557Sjimharris * This program is distributed in the hope that it will be useful, but 14230557Sjimharris * WITHOUT ANY WARRANTY; without even the implied warranty of 15230557Sjimharris * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16230557Sjimharris * General Public License for more details. 17230557Sjimharris * 18230557Sjimharris * You should have received a copy of the GNU General Public License 19230557Sjimharris * along with this program; if not, write to the Free Software 20230557Sjimharris * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 21230557Sjimharris * The full GNU General Public License is included in this distribution 22230557Sjimharris * in the file called LICENSE.GPL. 23230557Sjimharris * 24230557Sjimharris * BSD LICENSE 25230557Sjimharris * 26230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 27230557Sjimharris * All rights reserved. 28230557Sjimharris * 29230557Sjimharris * Redistribution and use in source and binary forms, with or without 30230557Sjimharris * modification, are permitted provided that the following conditions 31230557Sjimharris * are met: 32230557Sjimharris * 33230557Sjimharris * * Redistributions of source code must retain the above copyright 34230557Sjimharris * notice, this list of conditions and the following disclaimer. 35230557Sjimharris * * Redistributions in binary form must reproduce the above copyright 36230557Sjimharris * notice, this list of conditions and the following disclaimer in 37230557Sjimharris * the documentation and/or other materials provided with the 38230557Sjimharris * distribution. 39230557Sjimharris * 40230557Sjimharris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 41230557Sjimharris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 42230557Sjimharris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 43230557Sjimharris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 44230557Sjimharris * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45230557Sjimharris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 46230557Sjimharris * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 47230557Sjimharris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 48230557Sjimharris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49230557Sjimharris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 50230557Sjimharris * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51230557Sjimharris */ 52230557Sjimharris 53230557Sjimharris#include <sys/cdefs.h> 54230557Sjimharris__FBSDID("$FreeBSD$"); 55230557Sjimharris 56230557Sjimharris/** 57230557Sjimharris * @file 58230557Sjimharris * @brief This file contains the method implementations required to 59230557Sjimharris * translate the SCSI read (6, 10, 12, or 16-byte) commands. 60230557Sjimharris */ 61230557Sjimharris 62230557Sjimharris#include <dev/isci/scil/sati_move.h> 63230557Sjimharris#include <dev/isci/scil/sati_read.h> 64230557Sjimharris#include <dev/isci/scil/sati_callbacks.h> 65230557Sjimharris#include <dev/isci/scil/sati_util.h> 66230557Sjimharris 67230557Sjimharris#include <dev/isci/scil/intel_ata.h> 68230557Sjimharris#include <dev/isci/scil/intel_scsi.h> 69230557Sjimharris 70230557Sjimharris//****************************************************************************** 71230557Sjimharris//* P R I V A T E M E T H O D S 72230557Sjimharris//****************************************************************************** 73230557Sjimharris 74230557Sjimharris/** 75230557Sjimharris * @brief This method performs the common translation functionality for 76230557Sjimharris * all SCSI read operations that are 10 bytes in size or larger. 77230557Sjimharris * Translated/Written items include: 78230557Sjimharris * - Force Unit Access (FUA) 79230557Sjimharris * - Sector Count/Transfer Length 80230557Sjimharris * - Command register 81230557Sjimharris * 82230557Sjimharris * @param[in] sector_count This parameter specifies the number of sectors 83230557Sjimharris * to be transferred by this request. 84230557Sjimharris * @param[in] device_head This parameter points to device head register 85230557Sjimharris * that is to be written into the ATA task file (register FIS). 86230557Sjimharris * 87230557Sjimharris * @return Indicate if the command translation succeeded. 88230557Sjimharris * @see sati_move_set_sector_count() for additional return values. 89230557Sjimharris */ 90230557Sjimharrisstatic 91230557SjimharrisSATI_STATUS sati_read_large_translate_command( 92230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 93230557Sjimharris void * scsi_io, 94230557Sjimharris void * ata_io, 95230557Sjimharris U32 sector_count, 96230557Sjimharris U8 * device_head 97230557Sjimharris) 98230557Sjimharris{ 99230557Sjimharris sequence->data_direction = SATI_DATA_DIRECTION_IN; 100230557Sjimharris 101230557Sjimharris return sati_move_large_translate_command( 102230557Sjimharris sequence, 103230557Sjimharris scsi_io, 104230557Sjimharris ata_io, 105230557Sjimharris sector_count, 106230557Sjimharris device_head 107230557Sjimharris ); 108230557Sjimharris} 109230557Sjimharris 110230557Sjimharris/** 111230557Sjimharris * @brief This method performs the common translation functionality for 112230557Sjimharris * all SCSI read operations containing a 32-bit logical block 113230557Sjimharris * address. 114230557Sjimharris * Translated/Written items include: 115230557Sjimharris * - Logical Block Address (LBA) 116230557Sjimharris * - Force Unit Access (FUA) 117230557Sjimharris * - Sector Count/Transfer Length 118230557Sjimharris * - Command register 119230557Sjimharris * For more information on the parameters passed to this method, 120230557Sjimharris * please reference sati_translate_command(). 121230557Sjimharris * 122230557Sjimharris * @param[in] sector_count This parameter specifies the number of sectors 123230557Sjimharris * to be transferred by this request. 124230557Sjimharris * @param[in] control_byte_offset This parameter specifies the byte offset 125230557Sjimharris * into the command descriptor block at which the control byte 126230557Sjimharris * is located. 127230557Sjimharris * 128230557Sjimharris * @return Indicate if the command translation succeeded. 129230557Sjimharris * @see sati_move_32_bit_lba_translate_command(), sati_move_set_sector_count() 130230557Sjimharris * for additional return values. 131230557Sjimharris */ 132230557Sjimharrisstatic 133230557SjimharrisSATI_STATUS sati_read_32_bit_lba_translate_command( 134230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 135230557Sjimharris void * scsi_io, 136230557Sjimharris void * ata_io, 137230557Sjimharris U32 sector_count, 138230557Sjimharris U8 control_byte_offset 139230557Sjimharris) 140230557Sjimharris{ 141230557Sjimharris U8 device_head = 0; 142230557Sjimharris SATI_STATUS status; 143230557Sjimharris 144230557Sjimharris status = sati_read_large_translate_command( 145230557Sjimharris sequence, scsi_io, ata_io, sector_count, &device_head 146230557Sjimharris ); 147230557Sjimharris 148230557Sjimharris if (status == SATI_SUCCESS) 149230557Sjimharris { 150230557Sjimharris status = sati_move_32_bit_lba_translate_command( 151230557Sjimharris sequence, scsi_io, ata_io, device_head 152230557Sjimharris ); 153230557Sjimharris } 154230557Sjimharris 155230557Sjimharris return status; 156230557Sjimharris} 157230557Sjimharris 158230557Sjimharris//****************************************************************************** 159230557Sjimharris//* P U B L I C M E T H O D S 160230557Sjimharris//****************************************************************************** 161230557Sjimharris 162230557Sjimharris/** 163230557Sjimharris * @brief This method will translate the SCSI read command into a 164230557Sjimharris * corresponding ATA read 6 command. Depending upon the capabilities 165230557Sjimharris * supported by the target different ATA commands can be selected. 166230557Sjimharris * For more information on the parameters passed to this method, 167230557Sjimharris * please reference sati_translate_command(). 168230557Sjimharris * 169230557Sjimharris * @return Indicate if the command translation succeeded. 170230557Sjimharris * @retval SCI_SUCCESS This is returned if the command translation was 171230557Sjimharris * successful. 172230557Sjimharris * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if 173230557Sjimharris * sense data has been created as a result of something specified 174230557Sjimharris * in the CDB. 175230557Sjimharris */ 176230557SjimharrisSATI_STATUS sati_read_6_translate_command( 177230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 178230557Sjimharris void * scsi_io, 179230557Sjimharris void * ata_io 180230557Sjimharris) 181230557Sjimharris{ 182230557Sjimharris if(sati_device_state_stopped(sequence, scsi_io)) 183230557Sjimharris { 184230557Sjimharris return SATI_FAILURE_CHECK_RESPONSE_DATA; 185230557Sjimharris } 186230557Sjimharris else 187230557Sjimharris { 188230557Sjimharris sequence->data_direction = SATI_DATA_DIRECTION_IN; 189230557Sjimharris sequence->type = SATI_SEQUENCE_READ_6; 190230557Sjimharris 191230557Sjimharris return sati_move_small_translate_command(sequence, scsi_io, ata_io); 192230557Sjimharris } 193230557Sjimharris} 194230557Sjimharris 195230557Sjimharris/** 196230557Sjimharris * @brief This method will translate the SCSI read 10 command into a 197230557Sjimharris * corresponding ATA read command. Depending upon the capabilities 198230557Sjimharris * supported by the target different ATA commands can be selected. 199230557Sjimharris * It ensures that all translation required for this command is 200230557Sjimharris * performed successfully. 201230557Sjimharris * For more information on the parameters passed to this method, 202230557Sjimharris * please reference sati_translate_command(). 203230557Sjimharris * 204230557Sjimharris * @return Indicate if the command translation succeeded. 205230557Sjimharris * @see sati_read_32_bit_lba_translate_command() for return values. 206230557Sjimharris */ 207230557SjimharrisSATI_STATUS sati_read_10_translate_command( 208230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 209230557Sjimharris void * scsi_io, 210230557Sjimharris void * ata_io 211230557Sjimharris) 212230557Sjimharris{ 213230557Sjimharris 214230557Sjimharris U8 * cdb = sati_cb_get_cdb_address(scsi_io); 215230557Sjimharris 216230557Sjimharris U32 sector_count = (sati_get_cdb_byte(cdb, 7) << 8) | 217230557Sjimharris (sati_get_cdb_byte(cdb, 8)); 218230557Sjimharris 219230557Sjimharris if(sati_device_state_stopped(sequence, scsi_io)) 220230557Sjimharris { 221230557Sjimharris return SATI_FAILURE_CHECK_RESPONSE_DATA; 222230557Sjimharris } 223230557Sjimharris else 224230557Sjimharris { 225230557Sjimharris sequence->type = SATI_SEQUENCE_READ_10; 226230557Sjimharris 227230557Sjimharris return sati_read_32_bit_lba_translate_command( 228230557Sjimharris sequence, scsi_io, ata_io, sector_count, 9 229230557Sjimharris ); 230230557Sjimharris } 231230557Sjimharris} 232230557Sjimharris 233230557Sjimharris/** 234230557Sjimharris * @brief This method will translate the SCSI read 12 command into a 235230557Sjimharris * corresponding ATA read command. Depending upon the capabilities 236230557Sjimharris * supported by the target different ATA commands can be selected. 237230557Sjimharris * It ensures that all translation required for this command is 238230557Sjimharris * performed successfully. 239230557Sjimharris * For more information on the parameters passed to this method, 240230557Sjimharris * please reference sati_translate_command(). 241230557Sjimharris * 242230557Sjimharris * @return Indicate if the command translation succeeded. 243230557Sjimharris * @see sati_read_32_bit_lba_translate_command() for return values. 244230557Sjimharris */ 245230557SjimharrisSATI_STATUS sati_read_12_translate_command( 246230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 247230557Sjimharris void * scsi_io, 248230557Sjimharris void * ata_io 249230557Sjimharris) 250230557Sjimharris{ 251230557Sjimharris U8 * cdb = sati_cb_get_cdb_address(scsi_io); 252230557Sjimharris U32 sector_count = (sati_get_cdb_byte(cdb, 6) << 24) | 253230557Sjimharris (sati_get_cdb_byte(cdb, 7) << 16) | 254230557Sjimharris (sati_get_cdb_byte(cdb, 8) << 8) | 255230557Sjimharris (sati_get_cdb_byte(cdb, 9)); 256230557Sjimharris 257230557Sjimharris if(sati_device_state_stopped(sequence, scsi_io)) 258230557Sjimharris { 259230557Sjimharris return SATI_FAILURE_CHECK_RESPONSE_DATA; 260230557Sjimharris } 261230557Sjimharris else 262230557Sjimharris { 263230557Sjimharris sequence->type = SATI_SEQUENCE_READ_12; 264230557Sjimharris 265230557Sjimharris return sati_read_32_bit_lba_translate_command( 266230557Sjimharris sequence, scsi_io, ata_io, sector_count, 11 267230557Sjimharris ); 268230557Sjimharris } 269230557Sjimharris} 270230557Sjimharris 271230557Sjimharris/** 272230557Sjimharris * @brief This method will translate the SCSI read 16 command into a 273230557Sjimharris * corresponding ATA read command. Depending upon the capabilities 274230557Sjimharris * supported by the target different ATA commands can be selected. 275230557Sjimharris * It ensures that all translation required for this command is 276230557Sjimharris * performed successfully. 277230557Sjimharris * For more information on the parameters passed to this method, 278230557Sjimharris * please reference sati_translate_command(). 279230557Sjimharris * 280230557Sjimharris * @return Indicate if the command translation succeeded. 281230557Sjimharris * @see sati_read_large_translate_command(), sati_move_translate_64_bit_lba() 282230557Sjimharris * for additional return values. 283230557Sjimharris */ 284230557SjimharrisSATI_STATUS sati_read_16_translate_command( 285230557Sjimharris SATI_TRANSLATOR_SEQUENCE_T * sequence, 286230557Sjimharris void * scsi_io, 287230557Sjimharris void * ata_io 288230557Sjimharris) 289230557Sjimharris{ 290230557Sjimharris SATI_STATUS status; 291230557Sjimharris U8 device_head = 0; 292230557Sjimharris U8 * cdb = sati_cb_get_cdb_address(scsi_io); 293230557Sjimharris U32 sector_count = (sati_get_cdb_byte(cdb, 10) << 24) | 294230557Sjimharris (sati_get_cdb_byte(cdb, 11) << 16) | 295230557Sjimharris (sati_get_cdb_byte(cdb, 12) << 8) | 296230557Sjimharris (sati_get_cdb_byte(cdb, 13)); 297230557Sjimharris 298230557Sjimharris if(sati_device_state_stopped(sequence, scsi_io)) 299230557Sjimharris { 300230557Sjimharris return SATI_FAILURE_CHECK_RESPONSE_DATA; 301230557Sjimharris } 302230557Sjimharris else 303230557Sjimharris { 304230557Sjimharris sequence->type = SATI_SEQUENCE_READ_16; 305230557Sjimharris 306230557Sjimharris // Translate the sector count, write command register, and check various 307230557Sjimharris // other parts of the CDB. 308230557Sjimharris status = sati_read_large_translate_command( 309230557Sjimharris sequence, scsi_io, ata_io, sector_count, &device_head 310230557Sjimharris ); 311230557Sjimharris 312230557Sjimharris // Attempt to translate the 64-bit LBA field from the SCSI request 313230557Sjimharris // into the 48-bits of LBA in the ATA register FIS. 314230557Sjimharris if (status == SATI_SUCCESS) 315230557Sjimharris { 316230557Sjimharris sati_move_translate_command(sequence, scsi_io, ata_io, device_head); 317230557Sjimharris status = sati_move_translate_64_bit_lba(sequence, scsi_io, ata_io); 318230557Sjimharris } 319230557Sjimharris 320230557Sjimharris return status; 321230557Sjimharris } 322230557Sjimharris} 323230557Sjimharris 324