xref: /freebsd/sys/dev/isci/scil/scif_sas_sati_binding.h (revision fcb560670601b2a4d87bb31d7531c8dcc37ee71b)
1 /*-
2  * This file is provided under a dual BSD/GPLv2 license.  When using or
3  * redistributing this file, you may do so under either license.
4  *
5  * GPL LICENSE SUMMARY
6  *
7  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of version 2 of the GNU General Public License as
11  * published by the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21  * The full GNU General Public License is included in this distribution
22  * in the file called LICENSE.GPL.
23  *
24  * BSD LICENSE
25  *
26  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27  * All rights reserved.
28  *
29  * Redistribution and use in source and binary forms, with or without
30  * modification, are permitted provided that the following conditions
31  * are met:
32  *
33  *   * Redistributions of source code must retain the above copyright
34  *     notice, this list of conditions and the following disclaimer.
35  *   * Redistributions in binary form must reproduce the above copyright
36  *     notice, this list of conditions and the following disclaimer in
37  *     the documentation and/or other materials provided with the
38  *     distribution.
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
43  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
44  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51  *
52  * $FreeBSD$
53  */
54 #ifndef _SCIF_SAS_SATI_BINDING_H_
55 #define _SCIF_SAS_SATI_BINDING_H_
56 
57 /**
58  * @file
59  *
60  * @brief This file contains the SATI (SCSI to ATA Translation Implementation)
61  *        callback implementations that can be implemented by the SCI
62  *        Framework (or core in some cases).
63  */
64 
65 #ifdef __cplusplus
66 extern "C" {
67 #endif // __cplusplus
68 
69 #include <dev/isci/scil/scif_user_callback.h>
70 #include <dev/isci/scil/scif_io_request.h>
71 #include <dev/isci/scil/scif_remote_device.h>
72 #include <dev/isci/scil/scic_user_callback.h>
73 #include <dev/isci/scil/scic_io_request.h>
74 #include <dev/isci/scil/scic_remote_device.h>
75 //#include <dev/isci/scil/scic_sds_request.h>
76 //#include <dev/isci/scil/scu_task_context.h>
77 #include <dev/isci/scil/sci_object.h>
78 #include <dev/isci/scil/scif_sas_request.h>
79 #include <dev/isci/scil/sci_base_memory_descriptor_list.h>
80 #include <dev/isci/scil/scif_sas_stp_remote_device.h>
81 #include <dev/isci/scil/scif_sas_remote_device.h>
82 #include <dev/isci/scil/scif_sas_domain.h>
83 #include <dev/isci/scil/scif_sas_controller.h>
84 #include <dev/isci/scil/scic_sds_request.h>
85 #include <dev/isci/sci_environment.h>
86 
87 // SATI callbacks fulfilled by the framework user.
88 
89 #define sati_cb_get_data_byte(scsi_io, byte_offset, value)                    \
90 {                                                                             \
91    U8 * virtual_address = scif_cb_io_request_get_virtual_address_from_sgl(    \
92                              sci_object_get_association(scsi_io),(byte_offset)\
93                           );                                                  \
94    *(value) = *(virtual_address);                                             \
95 }
96 
97 #define sati_cb_set_data_byte(scsi_io, byte_offset, value)                    \
98 {                                                                             \
99    U8 * virtual_address = scif_cb_io_request_get_virtual_address_from_sgl(    \
100                              sci_object_get_association(scsi_io),(byte_offset)\
101                           );                                                  \
102    *(virtual_address) = value;                                                \
103 }
104 
105 #define sati_cb_get_cdb_address(scsi_io) \
106    scif_cb_io_request_get_cdb_address(sci_object_get_association(scsi_io))
107 
108 #define sati_cb_get_cdb_length(scsi_io)  \
109    scif_cb_io_request_get_cdb_length(sci_object_get_association(scsi_io))
110 
111 #define sati_cb_get_data_direction(scsi_io, sati_data_direction)              \
112 {                                                                             \
113    SCI_IO_REQUEST_DATA_DIRECTION sci_data_direction =                         \
114       scif_cb_io_request_get_data_direction(                                  \
115          sci_object_get_association(scsi_io)                                  \
116       );                                                                      \
117    if (sci_data_direction == SCI_IO_REQUEST_DATA_IN)                          \
118       *(sati_data_direction) = SATI_DATA_DIRECTION_IN;                        \
119    else if (sci_data_direction == SCI_IO_REQUEST_DATA_OUT)                    \
120       *(sati_data_direction) = SATI_DATA_DIRECTION_OUT;                       \
121    else if (sci_data_direction == SCI_IO_REQUEST_NO_DATA)                     \
122       *(sati_data_direction) = SATI_DATA_DIRECTION_NONE;                      \
123 }
124 
125 #define sati_cb_get_lun(scsi_io) \
126    scif_cb_io_request_get_lun(sci_object_get_association(scsi_io))
127 
128 // SATI callbacks fulfilled by the framework.
129 
130 /**
131  * This method implements the functionality necessary to fulfill the
132  * SCSI-to-ATA Translation requirements.  It ensures that the SAS
133  * address for the remote device associated with the supplied IO
134  * is written into the sas_address parameter.
135  * For more information on the parameters utilized in this method,
136  * please refer to sati_cb_device_get_sas_address().
137  */
138 #define sati_cb_device_get_sas_address(scsi_io, sas_address)               \
139 {                                                                          \
140    SCIF_SAS_REQUEST_T* fw_request = (SCIF_SAS_REQUEST_T*)scsi_io;          \
141    SCI_REMOTE_DEVICE_HANDLE_T scic_device                                  \
142       = scif_remote_device_get_scic_handle(fw_request->device);            \
143    scic_remote_device_get_sas_address(scic_device, sas_address);           \
144 }
145 
146 #define sati_cb_device_get_request_by_ncq_tag(scsi_io, ncq_tag, matching_req) \
147 {                                                                          \
148    SCIF_SAS_REQUEST_T* fw_request = (SCIF_SAS_REQUEST_T*)scsi_io;          \
149    SCIF_SAS_REMOTE_DEVICE_T* fw_device = fw_request->device;               \
150    matching_req = scif_sas_stp_remote_device_get_request_by_ncq_tag(fw_device, ncq_tag);  \
151 }
152 
153 #define sati_cb_io_request_complete(scsi_io, completion_status)            \
154 {                                                                          \
155    SCIF_SAS_REQUEST_T* fw_request = (SCIF_SAS_REQUEST_T*)scsi_io;          \
156    SCIF_SAS_REMOTE_DEVICE_T* fw_device = fw_request->device;               \
157    SCIF_SAS_DOMAIN_T*  fw_domain = fw_device->domain;                      \
158    SCIF_SAS_CONTROLLER_T* fw_controller = fw_domain->controller;           \
159    scif_cb_io_request_complete(                                            \
160       fw_controller, fw_device, fw_request, completion_status              \
161    );                                                                      \
162 }
163 
164 #define sati_cb_get_response_iu_address scif_io_request_get_response_iu_address
165 #define sati_cb_get_task_function       scic_cb_ssp_task_request_get_function
166 
167 #define sati_cb_get_ata_data_address(the_ata_io)          \
168    scic_io_request_get_rx_frame(                          \
169       scif_io_request_get_scic_handle((the_ata_io)), 0    \
170    )
171 
172 #define sati_cb_get_h2d_register_fis_address(the_ata_io)  \
173    (U8*) scic_stp_io_request_get_h2d_reg_address(         \
174             scif_io_request_get_scic_handle((the_ata_io)) \
175          )
176 
177 #define sati_cb_get_d2h_register_fis_address(the_ata_io)  \
178    (U8*) scic_stp_io_request_get_d2h_reg_address(         \
179             scif_io_request_get_scic_handle((the_ata_io)) \
180          )
181 
182 #define sati_cb_allocate_dma_buffer(scsi_io, length, virt_address, phys_address_low, phys_address_high) \
183 {                                                                 \
184    SCIF_SAS_REQUEST_T* fw_request = (SCIF_SAS_REQUEST_T*)scsi_io; \
185    SCI_PHYSICAL_MEMORY_DESCRIPTOR_T mde;                          \
186    mde.virtual_address = NULL;                                    \
187    sci_base_mde_construct(                                        \
188       &mde, 4, length, SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS    \
189    );                                                             \
190    scif_cb_controller_allocate_memory(                            \
191       fw_request->device->domain->controller, &mde                \
192    );                                                             \
193    *(virt_address)       = mde.virtual_address;                      \
194    *(phys_address_low)   = sci_cb_physical_address_lower(mde.physical_address); \
195    *(phys_address_high)  = sci_cb_physical_address_upper(mde.physical_address); \
196 }
197 
198 #define sati_cb_free_dma_buffer(scsi_io, virt_address)         \
199 {                                                                 \
200    SCIF_SAS_REQUEST_T* fw_request = (SCIF_SAS_REQUEST_T*)scsi_io; \
201    SCI_PHYSICAL_MEMORY_DESCRIPTOR_T mde;                          \
202    mde.virtual_address = virt_address;                         \
203    sci_base_mde_construct(                                        \
204       &mde, 4, 0, SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS         \
205    );                                                             \
206    scif_cb_controller_free_memory(                                \
207       fw_request->device->domain->controller, &mde                \
208    );                                                             \
209 }
210 
211 #define sati_cb_sgl_next_sge(scsi_io, ata_io, current_sge, next_sge) \
212 { \
213    /* For now just 2 SGEs are supported. */ \
214    SCIC_SDS_REQUEST_T *scic_request; \
215    SCU_SGL_ELEMENT_PAIR_T *sgl_pair; \
216    scic_request = scif_io_request_get_scic_handle((scsi_io)); \
217    sgl_pair     = scic_sds_request_get_sgl_element_pair(scic_request, 0); \
218  \
219    if ((current_sge) == NULL) \
220    { \
221       *(next_sge) = &(sgl_pair->A); \
222    } \
223    else \
224    { \
225       *(next_sge) = &(sgl_pair->B); \
226    } \
227 }
228 
229 #define sati_cb_sge_write(current_sge, phys_address_low, phys_address_high, byte_length) \
230 { \
231    SCU_SGL_ELEMENT_T * scu_sge = (SCU_SGL_ELEMENT_T*) (current_sge); \
232    scu_sge->address_upper      = (phys_address_high); \
233    scu_sge->address_lower      = (phys_address_low); \
234    scu_sge->length             = (byte_length); \
235    scu_sge->address_modifier   = 0; \
236 }
237 
238 #define sati_cb_do_translate_response(request) \
239     (request)->stp.sequence.is_translate_response_required
240 
241 #ifdef __cplusplus
242 }
243 #endif // __cplusplus
244 
245 #endif // _SCIF_SAS_SATI_BINDING_H_
246 
247