1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0 3 * 4 * This file is provided under a dual BSD/GPLv2 license. When using or 5 * redistributing this file, you may do so under either license. 6 * 7 * GPL LICENSE SUMMARY 8 * 9 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of version 2 of the GNU General Public License as 13 * published by the Free Software Foundation. 14 * 15 * This program is distributed in the hope that it will be useful, but 16 * WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 23 * The full GNU General Public License is included in this distribution 24 * in the file called LICENSE.GPL. 25 * 26 * BSD LICENSE 27 * 28 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 29 * All rights reserved. 30 * 31 * Redistribution and use in source and binary forms, with or without 32 * modification, are permitted provided that the following conditions 33 * are met: 34 * 35 * * Redistributions of source code must retain the above copyright 36 * notice, this list of conditions and the following disclaimer. 37 * * Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in 39 * the documentation and/or other materials provided with the 40 * distribution. 41 * 42 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 43 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 44 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 45 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 46 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 47 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 48 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 49 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 50 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 51 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 52 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 53 */ 54 55 #include <sys/cdefs.h> 56 /** 57 * @file 58 * @brief This file contains the method implementations required to 59 * translate the SCSI read (6, 10, 12, or 16-byte) commands. 60 */ 61 62 #include <dev/isci/scil/sati_move.h> 63 #include <dev/isci/scil/sati_read.h> 64 #include <dev/isci/scil/sati_callbacks.h> 65 #include <dev/isci/scil/sati_util.h> 66 67 #include <dev/isci/scil/intel_ata.h> 68 #include <dev/isci/scil/intel_scsi.h> 69 70 //****************************************************************************** 71 //* P R I V A T E M E T H O D S 72 //****************************************************************************** 73 74 /** 75 * @brief This method performs the common translation functionality for 76 * all SCSI read operations that are 10 bytes in size or larger. 77 * Translated/Written items include: 78 * - Force Unit Access (FUA) 79 * - Sector Count/Transfer Length 80 * - Command register 81 * 82 * @param[in] sector_count This parameter specifies the number of sectors 83 * to be transferred by this request. 84 * @param[in] device_head This parameter points to device head register 85 * that is to be written into the ATA task file (register FIS). 86 * 87 * @return Indicate if the command translation succeeded. 88 * @see sati_move_set_sector_count() for additional return values. 89 */ 90 static 91 SATI_STATUS sati_read_large_translate_command( 92 SATI_TRANSLATOR_SEQUENCE_T * sequence, 93 void * scsi_io, 94 void * ata_io, 95 U32 sector_count, 96 U8 * device_head 97 ) 98 { 99 sequence->data_direction = SATI_DATA_DIRECTION_IN; 100 101 return sati_move_large_translate_command( 102 sequence, 103 scsi_io, 104 ata_io, 105 sector_count, 106 device_head 107 ); 108 } 109 110 /** 111 * @brief This method performs the common translation functionality for 112 * all SCSI read operations containing a 32-bit logical block 113 * address. 114 * Translated/Written items include: 115 * - Logical Block Address (LBA) 116 * - Force Unit Access (FUA) 117 * - Sector Count/Transfer Length 118 * - Command register 119 * For more information on the parameters passed to this method, 120 * please reference sati_translate_command(). 121 * 122 * @param[in] sector_count This parameter specifies the number of sectors 123 * to be transferred by this request. 124 * @param[in] control_byte_offset This parameter specifies the byte offset 125 * into the command descriptor block at which the control byte 126 * is located. 127 * 128 * @return Indicate if the command translation succeeded. 129 * @see sati_move_32_bit_lba_translate_command(), sati_move_set_sector_count() 130 * for additional return values. 131 */ 132 static 133 SATI_STATUS sati_read_32_bit_lba_translate_command( 134 SATI_TRANSLATOR_SEQUENCE_T * sequence, 135 void * scsi_io, 136 void * ata_io, 137 U32 sector_count, 138 U8 control_byte_offset 139 ) 140 { 141 U8 device_head = 0; 142 SATI_STATUS status; 143 144 status = sati_read_large_translate_command( 145 sequence, scsi_io, ata_io, sector_count, &device_head 146 ); 147 148 if (status == SATI_SUCCESS) 149 { 150 status = sati_move_32_bit_lba_translate_command( 151 sequence, scsi_io, ata_io, device_head 152 ); 153 } 154 155 return status; 156 } 157 158 //****************************************************************************** 159 //* P U B L I C M E T H O D S 160 //****************************************************************************** 161 162 /** 163 * @brief This method will translate the SCSI read command into a 164 * corresponding ATA read 6 command. Depending upon the capabilities 165 * supported by the target different ATA commands can be selected. 166 * For more information on the parameters passed to this method, 167 * please reference sati_translate_command(). 168 * 169 * @return Indicate if the command translation succeeded. 170 * @retval SCI_SUCCESS This is returned if the command translation was 171 * successful. 172 * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if 173 * sense data has been created as a result of something specified 174 * in the CDB. 175 */ 176 SATI_STATUS sati_read_6_translate_command( 177 SATI_TRANSLATOR_SEQUENCE_T * sequence, 178 void * scsi_io, 179 void * ata_io 180 ) 181 { 182 if(sati_device_state_stopped(sequence, scsi_io)) 183 { 184 return SATI_FAILURE_CHECK_RESPONSE_DATA; 185 } 186 else 187 { 188 sequence->data_direction = SATI_DATA_DIRECTION_IN; 189 sequence->type = SATI_SEQUENCE_READ_6; 190 191 return sati_move_small_translate_command(sequence, scsi_io, ata_io); 192 } 193 } 194 195 /** 196 * @brief This method will translate the SCSI read 10 command into a 197 * corresponding ATA read command. Depending upon the capabilities 198 * supported by the target different ATA commands can be selected. 199 * It ensures that all translation required for this command is 200 * performed successfully. 201 * For more information on the parameters passed to this method, 202 * please reference sati_translate_command(). 203 * 204 * @return Indicate if the command translation succeeded. 205 * @see sati_read_32_bit_lba_translate_command() for return values. 206 */ 207 SATI_STATUS sati_read_10_translate_command( 208 SATI_TRANSLATOR_SEQUENCE_T * sequence, 209 void * scsi_io, 210 void * ata_io 211 ) 212 { 213 214 U8 * cdb = sati_cb_get_cdb_address(scsi_io); 215 216 U32 sector_count = (sati_get_cdb_byte(cdb, 7) << 8) | 217 (sati_get_cdb_byte(cdb, 8)); 218 219 if(sati_device_state_stopped(sequence, scsi_io)) 220 { 221 return SATI_FAILURE_CHECK_RESPONSE_DATA; 222 } 223 else 224 { 225 sequence->type = SATI_SEQUENCE_READ_10; 226 227 return sati_read_32_bit_lba_translate_command( 228 sequence, scsi_io, ata_io, sector_count, 9 229 ); 230 } 231 } 232 233 /** 234 * @brief This method will translate the SCSI read 12 command into a 235 * corresponding ATA read command. Depending upon the capabilities 236 * supported by the target different ATA commands can be selected. 237 * It ensures that all translation required for this command is 238 * performed successfully. 239 * For more information on the parameters passed to this method, 240 * please reference sati_translate_command(). 241 * 242 * @return Indicate if the command translation succeeded. 243 * @see sati_read_32_bit_lba_translate_command() for return values. 244 */ 245 SATI_STATUS sati_read_12_translate_command( 246 SATI_TRANSLATOR_SEQUENCE_T * sequence, 247 void * scsi_io, 248 void * ata_io 249 ) 250 { 251 U8 * cdb = sati_cb_get_cdb_address(scsi_io); 252 U32 sector_count = (sati_get_cdb_byte(cdb, 6) << 24) | 253 (sati_get_cdb_byte(cdb, 7) << 16) | 254 (sati_get_cdb_byte(cdb, 8) << 8) | 255 (sati_get_cdb_byte(cdb, 9)); 256 257 if(sati_device_state_stopped(sequence, scsi_io)) 258 { 259 return SATI_FAILURE_CHECK_RESPONSE_DATA; 260 } 261 else 262 { 263 sequence->type = SATI_SEQUENCE_READ_12; 264 265 return sati_read_32_bit_lba_translate_command( 266 sequence, scsi_io, ata_io, sector_count, 11 267 ); 268 } 269 } 270 271 /** 272 * @brief This method will translate the SCSI read 16 command into a 273 * corresponding ATA read command. Depending upon the capabilities 274 * supported by the target different ATA commands can be selected. 275 * It ensures that all translation required for this command is 276 * performed successfully. 277 * For more information on the parameters passed to this method, 278 * please reference sati_translate_command(). 279 * 280 * @return Indicate if the command translation succeeded. 281 * @see sati_read_large_translate_command(), sati_move_translate_64_bit_lba() 282 * for additional return values. 283 */ 284 SATI_STATUS sati_read_16_translate_command( 285 SATI_TRANSLATOR_SEQUENCE_T * sequence, 286 void * scsi_io, 287 void * ata_io 288 ) 289 { 290 SATI_STATUS status; 291 U8 device_head = 0; 292 U8 * cdb = sati_cb_get_cdb_address(scsi_io); 293 U32 sector_count = (sati_get_cdb_byte(cdb, 10) << 24) | 294 (sati_get_cdb_byte(cdb, 11) << 16) | 295 (sati_get_cdb_byte(cdb, 12) << 8) | 296 (sati_get_cdb_byte(cdb, 13)); 297 298 if(sati_device_state_stopped(sequence, scsi_io)) 299 { 300 return SATI_FAILURE_CHECK_RESPONSE_DATA; 301 } 302 else 303 { 304 sequence->type = SATI_SEQUENCE_READ_16; 305 306 // Translate the sector count, write command register, and check various 307 // other parts of the CDB. 308 status = sati_read_large_translate_command( 309 sequence, scsi_io, ata_io, sector_count, &device_head 310 ); 311 312 // Attempt to translate the 64-bit LBA field from the SCSI request 313 // into the 48-bits of LBA in the ATA register FIS. 314 if (status == SATI_SUCCESS) 315 { 316 sati_move_translate_command(sequence, scsi_io, ata_io, device_head); 317 status = sati_move_translate_64_bit_lba(sequence, scsi_io, ata_io); 318 } 319 320 return status; 321 } 322 } 323 324