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 * $FreeBSD$ 55 */ 56 #ifndef _SCIF_SAS_SATI_BINDING_H_ 57 #define _SCIF_SAS_SATI_BINDING_H_ 58 59 /** 60 * @file 61 * 62 * @brief This file contains the SATI (SCSI to ATA Translation Implementation) 63 * callback implementations that can be implemented by the SCI 64 * Framework (or core in some cases). 65 */ 66 67 #ifdef __cplusplus 68 extern "C" { 69 #endif // __cplusplus 70 71 #include <dev/isci/scil/scif_user_callback.h> 72 #include <dev/isci/scil/scif_io_request.h> 73 #include <dev/isci/scil/scif_remote_device.h> 74 #include <dev/isci/scil/scic_user_callback.h> 75 #include <dev/isci/scil/scic_io_request.h> 76 #include <dev/isci/scil/scic_remote_device.h> 77 //#include <dev/isci/scil/scic_sds_request.h> 78 //#include <dev/isci/scil/scu_task_context.h> 79 #include <dev/isci/scil/sci_object.h> 80 #include <dev/isci/scil/scif_sas_request.h> 81 #include <dev/isci/scil/sci_base_memory_descriptor_list.h> 82 #include <dev/isci/scil/scif_sas_stp_remote_device.h> 83 #include <dev/isci/scil/scif_sas_remote_device.h> 84 #include <dev/isci/scil/scif_sas_domain.h> 85 #include <dev/isci/scil/scif_sas_controller.h> 86 #include <dev/isci/scil/scic_sds_request.h> 87 #include <dev/isci/sci_environment.h> 88 89 // SATI callbacks fulfilled by the framework user. 90 91 #define sati_cb_get_data_byte(scsi_io, byte_offset, value) \ 92 { \ 93 U8 * virtual_address = scif_cb_io_request_get_virtual_address_from_sgl( \ 94 sci_object_get_association(scsi_io),(byte_offset)\ 95 ); \ 96 *(value) = *(virtual_address); \ 97 } 98 99 #define sati_cb_set_data_byte(scsi_io, byte_offset, value) \ 100 { \ 101 U8 * virtual_address = scif_cb_io_request_get_virtual_address_from_sgl( \ 102 sci_object_get_association(scsi_io),(byte_offset)\ 103 ); \ 104 *(virtual_address) = value; \ 105 } 106 107 #define sati_cb_get_cdb_address(scsi_io) \ 108 scif_cb_io_request_get_cdb_address(sci_object_get_association(scsi_io)) 109 110 #define sati_cb_get_cdb_length(scsi_io) \ 111 scif_cb_io_request_get_cdb_length(sci_object_get_association(scsi_io)) 112 113 #define sati_cb_get_data_direction(scsi_io, sati_data_direction) \ 114 { \ 115 SCI_IO_REQUEST_DATA_DIRECTION sci_data_direction = \ 116 scif_cb_io_request_get_data_direction( \ 117 sci_object_get_association(scsi_io) \ 118 ); \ 119 if (sci_data_direction == SCI_IO_REQUEST_DATA_IN) \ 120 *(sati_data_direction) = SATI_DATA_DIRECTION_IN; \ 121 else if (sci_data_direction == SCI_IO_REQUEST_DATA_OUT) \ 122 *(sati_data_direction) = SATI_DATA_DIRECTION_OUT; \ 123 else if (sci_data_direction == SCI_IO_REQUEST_NO_DATA) \ 124 *(sati_data_direction) = SATI_DATA_DIRECTION_NONE; \ 125 } 126 127 #define sati_cb_get_lun(scsi_io) \ 128 scif_cb_io_request_get_lun(sci_object_get_association(scsi_io)) 129 130 // SATI callbacks fulfilled by the framework. 131 132 /** 133 * This method implements the functionality necessary to fulfill the 134 * SCSI-to-ATA Translation requirements. It ensures that the SAS 135 * address for the remote device associated with the supplied IO 136 * is written into the sas_address parameter. 137 * For more information on the parameters utilized in this method, 138 * please refer to sati_cb_device_get_sas_address(). 139 */ 140 #define sati_cb_device_get_sas_address(scsi_io, sas_address) \ 141 { \ 142 SCIF_SAS_REQUEST_T* fw_request = (SCIF_SAS_REQUEST_T*)scsi_io; \ 143 SCI_REMOTE_DEVICE_HANDLE_T scic_device \ 144 = scif_remote_device_get_scic_handle(fw_request->device); \ 145 scic_remote_device_get_sas_address(scic_device, sas_address); \ 146 } 147 148 #define sati_cb_device_get_request_by_ncq_tag(scsi_io, ncq_tag, matching_req) \ 149 { \ 150 SCIF_SAS_REQUEST_T* fw_request = (SCIF_SAS_REQUEST_T*)scsi_io; \ 151 SCIF_SAS_REMOTE_DEVICE_T* fw_device = fw_request->device; \ 152 matching_req = scif_sas_stp_remote_device_get_request_by_ncq_tag(fw_device, ncq_tag); \ 153 } 154 155 #define sati_cb_io_request_complete(scsi_io, completion_status) \ 156 { \ 157 SCIF_SAS_REQUEST_T* fw_request = (SCIF_SAS_REQUEST_T*)scsi_io; \ 158 SCIF_SAS_REMOTE_DEVICE_T* fw_device = fw_request->device; \ 159 SCIF_SAS_DOMAIN_T* fw_domain = fw_device->domain; \ 160 SCIF_SAS_CONTROLLER_T* fw_controller = fw_domain->controller; \ 161 scif_cb_io_request_complete( \ 162 fw_controller, fw_device, fw_request, completion_status \ 163 ); \ 164 } 165 166 #define sati_cb_get_response_iu_address scif_io_request_get_response_iu_address 167 #define sati_cb_get_task_function scic_cb_ssp_task_request_get_function 168 169 #define sati_cb_get_ata_data_address(the_ata_io) \ 170 scic_io_request_get_rx_frame( \ 171 scif_io_request_get_scic_handle((the_ata_io)), 0 \ 172 ) 173 174 #define sati_cb_get_h2d_register_fis_address(the_ata_io) \ 175 (U8*) scic_stp_io_request_get_h2d_reg_address( \ 176 scif_io_request_get_scic_handle((the_ata_io)) \ 177 ) 178 179 #define sati_cb_get_d2h_register_fis_address(the_ata_io) \ 180 (U8*) scic_stp_io_request_get_d2h_reg_address( \ 181 scif_io_request_get_scic_handle((the_ata_io)) \ 182 ) 183 184 #define sati_cb_allocate_dma_buffer(scsi_io, length, virt_address, phys_address_low, phys_address_high) \ 185 { \ 186 SCIF_SAS_REQUEST_T* fw_request = (SCIF_SAS_REQUEST_T*)scsi_io; \ 187 SCI_PHYSICAL_MEMORY_DESCRIPTOR_T mde; \ 188 mde.virtual_address = NULL; \ 189 sci_base_mde_construct( \ 190 &mde, 4, length, SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS \ 191 ); \ 192 scif_cb_controller_allocate_memory( \ 193 fw_request->device->domain->controller, &mde \ 194 ); \ 195 *(virt_address) = mde.virtual_address; \ 196 *(phys_address_low) = sci_cb_physical_address_lower(mde.physical_address); \ 197 *(phys_address_high) = sci_cb_physical_address_upper(mde.physical_address); \ 198 } 199 200 #define sati_cb_free_dma_buffer(scsi_io, virt_address) \ 201 { \ 202 SCIF_SAS_REQUEST_T* fw_request = (SCIF_SAS_REQUEST_T*)scsi_io; \ 203 SCI_PHYSICAL_MEMORY_DESCRIPTOR_T mde; \ 204 mde.virtual_address = virt_address; \ 205 sci_base_mde_construct( \ 206 &mde, 4, 0, SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS \ 207 ); \ 208 scif_cb_controller_free_memory( \ 209 fw_request->device->domain->controller, &mde \ 210 ); \ 211 } 212 213 #define sati_cb_sgl_next_sge(scsi_io, ata_io, current_sge, next_sge) \ 214 { \ 215 /* For now just 2 SGEs are supported. */ \ 216 SCIC_SDS_REQUEST_T *scic_request; \ 217 SCU_SGL_ELEMENT_PAIR_T *sgl_pair; \ 218 scic_request = scif_io_request_get_scic_handle((scsi_io)); \ 219 sgl_pair = scic_sds_request_get_sgl_element_pair(scic_request, 0); \ 220 \ 221 if ((current_sge) == NULL) \ 222 { \ 223 *(next_sge) = &(sgl_pair->A); \ 224 } \ 225 else \ 226 { \ 227 *(next_sge) = &(sgl_pair->B); \ 228 } \ 229 } 230 231 #define sati_cb_sge_write(current_sge, phys_address_low, phys_address_high, byte_length) \ 232 { \ 233 SCU_SGL_ELEMENT_T * scu_sge = (SCU_SGL_ELEMENT_T*) (current_sge); \ 234 scu_sge->address_upper = (phys_address_high); \ 235 scu_sge->address_lower = (phys_address_low); \ 236 scu_sge->length = (byte_length); \ 237 scu_sge->address_modifier = 0; \ 238 } 239 240 #define sati_cb_do_translate_response(request) \ 241 (request)->stp.sequence.is_translate_response_required 242 243 #ifdef __cplusplus 244 } 245 #endif // __cplusplus 246 247 #endif // _SCIF_SAS_SATI_BINDING_H_ 248 249