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 write (6, 10, 12, or 16-byte) commands. 60 */ 61 62 #include <dev/isci/scil/sati_move.h> 63 #include <dev/isci/scil/sati_write.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 write 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_write_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_OUT; 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 write 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_write_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_write_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 write command into a 164 * corresponding ATA write 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_write_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_OUT; 189 sequence->type = SATI_SEQUENCE_WRITE_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 write 10 command into a 197 * corresponding ATA write 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_write_32_bit_lba_translate_command() for return values. 206 */ 207 SATI_STATUS sati_write_10_translate_command( 208 SATI_TRANSLATOR_SEQUENCE_T * sequence, 209 void * scsi_io, 210 void * ata_io 211 ) 212 { 213 U8 * cdb = sati_cb_get_cdb_address(scsi_io); 214 U32 sector_count = (sati_get_cdb_byte(cdb, 7) << 8) | 215 (sati_get_cdb_byte(cdb, 8)); 216 217 if(sati_device_state_stopped(sequence, scsi_io)) 218 { 219 return SATI_FAILURE_CHECK_RESPONSE_DATA; 220 } 221 else 222 { 223 sequence->type = SATI_SEQUENCE_WRITE_10; 224 225 return sati_write_32_bit_lba_translate_command( 226 sequence, scsi_io, ata_io, sector_count, 9 227 ); 228 } 229 } 230 231 /** 232 * @brief This method will translate the SCSI write 12 command into a 233 * corresponding ATA write command. Depending upon the capabilities 234 * supported by the target different ATA commands can be selected. 235 * It ensures that all translation required for this command is 236 * performed successfully. 237 * For more information on the parameters passed to this method, 238 * please reference sati_translate_command(). 239 * 240 * @return Indicate if the command translation succeeded. 241 * @see sati_write_32_bit_lba_translate_command() for return values. 242 */ 243 SATI_STATUS sati_write_12_translate_command( 244 SATI_TRANSLATOR_SEQUENCE_T * sequence, 245 void * scsi_io, 246 void * ata_io 247 ) 248 { 249 U8 * cdb = sati_cb_get_cdb_address(scsi_io); 250 U32 sector_count = (sati_get_cdb_byte(cdb, 6) << 24) | 251 (sati_get_cdb_byte(cdb, 7) << 16) | 252 (sati_get_cdb_byte(cdb, 8) << 8) | 253 (sati_get_cdb_byte(cdb, 9)); 254 255 if(sati_device_state_stopped(sequence, scsi_io)) 256 { 257 return SATI_FAILURE_CHECK_RESPONSE_DATA; 258 } 259 else 260 { 261 sequence->type = SATI_SEQUENCE_WRITE_12; 262 263 return sati_write_32_bit_lba_translate_command( 264 sequence, scsi_io, ata_io, sector_count, 11 265 ); 266 } 267 } 268 269 /** 270 * @brief This method will translate the SCSI write 16 command into a 271 * corresponding ATA write command. Depending upon the capabilities 272 * supported by the target different ATA commands can be selected. 273 * It ensures that all translation required for this command is 274 * performed successfully. 275 * For more information on the parameters passed to this method, 276 * please reference sati_translate_command(). 277 * 278 * @return Indicate if the command translation succeeded. 279 * @see sati_write_large_translate_command(), sati_move_translate_64_bit_lba() 280 * for additional return values. 281 */ 282 SATI_STATUS sati_write_16_translate_command( 283 SATI_TRANSLATOR_SEQUENCE_T * sequence, 284 void * scsi_io, 285 void * ata_io 286 ) 287 { 288 SATI_STATUS status; 289 U8 device_head = 0; 290 U8 * cdb = sati_cb_get_cdb_address(scsi_io); 291 U32 sector_count = (sati_get_cdb_byte(cdb, 10) << 24) | 292 (sati_get_cdb_byte(cdb, 11) << 16) | 293 (sati_get_cdb_byte(cdb, 12) << 8) | 294 (sati_get_cdb_byte(cdb, 13)); 295 296 if(sati_device_state_stopped(sequence, scsi_io)) 297 { 298 return SATI_FAILURE_CHECK_RESPONSE_DATA; 299 } 300 else 301 { 302 sequence->type = SATI_SEQUENCE_WRITE_16; 303 304 // Translate the sector count, write command register, and check various 305 // other parts of the CDB. 306 status = sati_write_large_translate_command( 307 sequence, scsi_io, ata_io, sector_count, &device_head 308 ); 309 310 // Attempt to translate the 64-bit LBA field from the SCSI request 311 // into the 48-bits of LBA in the ATA register FIS. 312 if (status == SATI_SUCCESS) 313 { 314 sati_move_translate_command(sequence, scsi_io, ata_io, device_head); 315 status = sati_move_translate_64_bit_lba(sequence, scsi_io, ata_io); 316 } 317 318 return status; 319 } 320 } 321 322