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 __FBSDID("$FreeBSD$"); 57 58 /** 59 * @file 60 * @brief This file contains the method implementations required to 61 * translate the SCSI write (6, 10, 12, or 16-byte) commands. 62 */ 63 64 #include <dev/isci/scil/sati_move.h> 65 #include <dev/isci/scil/sati_write.h> 66 #include <dev/isci/scil/sati_callbacks.h> 67 #include <dev/isci/scil/sati_util.h> 68 69 #include <dev/isci/scil/intel_ata.h> 70 #include <dev/isci/scil/intel_scsi.h> 71 72 //****************************************************************************** 73 //* P R I V A T E M E T H O D S 74 //****************************************************************************** 75 76 /** 77 * @brief This method performs the common translation functionality for 78 * all SCSI write operations that are 10 bytes in size or larger. 79 * Translated/Written items include: 80 * - Force Unit Access (FUA) 81 * - Sector Count/Transfer Length 82 * - Command register 83 * 84 * @param[in] sector_count This parameter specifies the number of sectors 85 * to be transferred by this request. 86 * @param[in] device_head This parameter points to device head register 87 * that is to be written into the ATA task file (register FIS). 88 * 89 * @return Indicate if the command translation succeeded. 90 * @see sati_move_set_sector_count() for additional return values. 91 */ 92 static 93 SATI_STATUS sati_write_large_translate_command( 94 SATI_TRANSLATOR_SEQUENCE_T * sequence, 95 void * scsi_io, 96 void * ata_io, 97 U32 sector_count, 98 U8 * device_head 99 ) 100 { 101 sequence->data_direction = SATI_DATA_DIRECTION_OUT; 102 103 return sati_move_large_translate_command( 104 sequence, 105 scsi_io, 106 ata_io, 107 sector_count, 108 device_head 109 ); 110 } 111 112 /** 113 * @brief This method performs the common translation functionality for 114 * all SCSI write operations containing a 32-bit logical block 115 * address. 116 * Translated/Written items include: 117 * - Logical Block Address (LBA) 118 * - Force Unit Access (FUA) 119 * - Sector Count/Transfer Length 120 * - Command register 121 * For more information on the parameters passed to this method, 122 * please reference sati_translate_command(). 123 * 124 * @param[in] sector_count This parameter specifies the number of sectors 125 * to be transferred by this request. 126 * @param[in] control_byte_offset This parameter specifies the byte offset 127 * into the command descriptor block at which the control byte 128 * is located. 129 * 130 * @return Indicate if the command translation succeeded. 131 * @see sati_move_32_bit_lba_translate_command(), sati_move_set_sector_count() 132 * for additional return values. 133 */ 134 static 135 SATI_STATUS sati_write_32_bit_lba_translate_command( 136 SATI_TRANSLATOR_SEQUENCE_T * sequence, 137 void * scsi_io, 138 void * ata_io, 139 U32 sector_count, 140 U8 control_byte_offset 141 ) 142 { 143 U8 device_head = 0; 144 SATI_STATUS status; 145 146 status = sati_write_large_translate_command( 147 sequence, scsi_io, ata_io, sector_count, &device_head 148 ); 149 150 if (status == SATI_SUCCESS) 151 { 152 status = sati_move_32_bit_lba_translate_command( 153 sequence, scsi_io, ata_io, device_head 154 ); 155 } 156 157 return status; 158 } 159 160 //****************************************************************************** 161 //* P U B L I C M E T H O D S 162 //****************************************************************************** 163 164 /** 165 * @brief This method will translate the SCSI write command into a 166 * corresponding ATA write 6 command. Depending upon the capabilities 167 * supported by the target different ATA commands can be selected. 168 * For more information on the parameters passed to this method, 169 * please reference sati_translate_command(). 170 * 171 * @return Indicate if the command translation succeeded. 172 * @retval SCI_SUCCESS This is returned if the command translation was 173 * successful. 174 * @retval SATI_FAILURE_CHECK_RESPONSE_DATA This value is returned if 175 * sense data has been created as a result of something specified 176 * in the CDB. 177 */ 178 SATI_STATUS sati_write_6_translate_command( 179 SATI_TRANSLATOR_SEQUENCE_T * sequence, 180 void * scsi_io, 181 void * ata_io 182 ) 183 { 184 if(sati_device_state_stopped(sequence, scsi_io)) 185 { 186 return SATI_FAILURE_CHECK_RESPONSE_DATA; 187 } 188 else 189 { 190 sequence->data_direction = SATI_DATA_DIRECTION_OUT; 191 sequence->type = SATI_SEQUENCE_WRITE_6; 192 193 return sati_move_small_translate_command(sequence, scsi_io, ata_io); 194 } 195 } 196 197 /** 198 * @brief This method will translate the SCSI write 10 command into a 199 * corresponding ATA write command. Depending upon the capabilities 200 * supported by the target different ATA commands can be selected. 201 * It ensures that all translation required for this command is 202 * performed successfully. 203 * For more information on the parameters passed to this method, 204 * please reference sati_translate_command(). 205 * 206 * @return Indicate if the command translation succeeded. 207 * @see sati_write_32_bit_lba_translate_command() for return values. 208 */ 209 SATI_STATUS sati_write_10_translate_command( 210 SATI_TRANSLATOR_SEQUENCE_T * sequence, 211 void * scsi_io, 212 void * ata_io 213 ) 214 { 215 U8 * cdb = sati_cb_get_cdb_address(scsi_io); 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_WRITE_10; 226 227 return sati_write_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 write 12 command into a 235 * corresponding ATA write 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_write_32_bit_lba_translate_command() for return values. 244 */ 245 SATI_STATUS sati_write_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_WRITE_12; 264 265 return sati_write_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 write 16 command into a 273 * corresponding ATA write 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_write_large_translate_command(), sati_move_translate_64_bit_lba() 282 * for additional return values. 283 */ 284 SATI_STATUS sati_write_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_WRITE_16; 305 306 // Translate the sector count, write command register, and check various 307 // other parts of the CDB. 308 status = sati_write_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