Commit | Line | Data |
---|---|---|
6f231dda DW |
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 | * * Neither the name of Intel Corporation nor the names of its | |
40 | * contributors may be used to endorse or promote products derived | |
41 | * from this software without specific prior written permission. | |
42 | * | |
43 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
44 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
45 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
46 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
47 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
48 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
49 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
50 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
51 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
52 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
53 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
54 | */ | |
55 | ||
56 | #ifndef _SCIC_SDS_IO_REQUEST_H_ | |
57 | #define _SCIC_SDS_IO_REQUEST_H_ | |
58 | ||
59 | /** | |
60 | * This file contains the structures, constants and prototypes for the | |
61 | * SCIC_SDS_IO_REQUEST object. | |
62 | * | |
63 | * | |
64 | */ | |
65 | ||
66 | #include "scic_io_request.h" | |
67 | ||
68 | #include "sci_base_request.h" | |
69 | #include "scu_task_context.h" | |
70 | #include "intel_sas.h" | |
71 | ||
72 | struct scic_sds_controller; | |
73 | struct scic_sds_remote_device; | |
74 | struct scic_sds_io_request_state_handler; | |
75 | ||
76 | /** | |
77 | * enum _SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATES - This enumeration | |
78 | * depicts all of the substates for a task management request to be | |
79 | * performed in the STARTED super-state. | |
80 | * | |
81 | * | |
82 | */ | |
83 | enum scic_sds_raw_request_started_task_mgmt_substates { | |
84 | /** | |
85 | * The AWAIT_TC_COMPLETION sub-state indicates that the started raw | |
86 | * task management request is waiting for the transmission of the | |
87 | * initial frame (i.e. command, task, etc.). | |
88 | */ | |
89 | SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION, | |
90 | ||
91 | /** | |
92 | * This sub-state indicates that the started task management request | |
93 | * is waiting for the reception of an unsolicited frame | |
94 | * (i.e. response IU). | |
95 | */ | |
96 | SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE, | |
97 | }; | |
98 | ||
99 | ||
100 | /** | |
101 | * enum _SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATES - This enumeration depicts all | |
102 | * of the substates for a SMP request to be performed in the STARTED | |
103 | * super-state. | |
104 | * | |
105 | * | |
106 | */ | |
107 | enum scic_sds_smp_request_started_substates { | |
108 | /** | |
109 | * This sub-state indicates that the started task management request | |
110 | * is waiting for the reception of an unsolicited frame | |
111 | * (i.e. response IU). | |
112 | */ | |
113 | SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE, | |
114 | ||
115 | /** | |
116 | * The AWAIT_TC_COMPLETION sub-state indicates that the started SMP request is | |
117 | * waiting for the transmission of the initial frame (i.e. command, task, etc.). | |
118 | */ | |
119 | SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION, | |
120 | }; | |
121 | ||
122 | /** | |
123 | * struct SCIC_SDS_IO_REQUEST - This structure contains or references all of | |
124 | * the data necessary to process a task management or normal IO request. | |
125 | * | |
126 | * | |
127 | */ | |
128 | struct scic_sds_request { | |
129 | /** | |
130 | * This field indictes the parent object of the request. | |
131 | */ | |
132 | struct sci_base_request parent; | |
133 | ||
134 | void *user_request; | |
135 | ||
136 | /** | |
137 | * This field simply points to the controller to which this IO request | |
138 | * is associated. | |
139 | */ | |
140 | struct scic_sds_controller *owning_controller; | |
141 | ||
142 | /** | |
143 | * This field simply points to the remote device to which this IO request | |
144 | * is associated. | |
145 | */ | |
146 | struct scic_sds_remote_device *target_device; | |
147 | ||
148 | /** | |
149 | * This field is utilized to determine if the SCI user is managing | |
150 | * the IO tag for this request or if the core is managing it. | |
151 | */ | |
152 | bool was_tag_assigned_by_user; | |
153 | ||
154 | /** | |
155 | * This field indicates the IO tag for this request. The IO tag is | |
156 | * comprised of the task_index and a sequence count. The sequence count | |
157 | * is utilized to help identify tasks from one life to another. | |
158 | */ | |
159 | u16 io_tag; | |
160 | ||
161 | /** | |
162 | * This field specifies the protocol being utilized for this | |
163 | * IO request. | |
164 | */ | |
165 | SCIC_TRANSPORT_PROTOCOL protocol; | |
166 | ||
167 | /** | |
168 | * This field indicates the completion status taken from the SCUs | |
169 | * completion code. It indicates the completion result for the SCU hardware. | |
170 | */ | |
171 | u32 scu_status; | |
172 | ||
173 | /** | |
174 | * This field indicates the completion status returned to the SCI user. It | |
175 | * indicates the users view of the io request completion. | |
176 | */ | |
177 | u32 sci_status; | |
178 | ||
179 | /** | |
180 | * This field contains the value to be utilized when posting (e.g. Post_TC, | |
181 | * Post_TC_Abort) this request to the silicon. | |
182 | */ | |
183 | u32 post_context; | |
184 | ||
185 | void *command_buffer; | |
186 | void *response_buffer; | |
187 | struct scu_task_context *task_context_buffer; | |
188 | struct scu_sgl_element_pair *sgl_element_pair_buffer; | |
189 | ||
190 | /** | |
191 | * This field indicates if this request is a task management request or | |
192 | * normal IO request. | |
193 | */ | |
194 | bool is_task_management_request; | |
195 | ||
196 | /** | |
197 | * This field indicates that this request contains an initialized started | |
198 | * substate machine. | |
199 | */ | |
200 | bool has_started_substate_machine; | |
201 | ||
202 | /** | |
203 | * This field is a pointer to the stored rx frame data. It is used in STP | |
204 | * internal requests and SMP response frames. If this field is non-NULL the | |
205 | * saved frame must be released on IO request completion. | |
206 | * | |
207 | * @todo In the future do we want to keep a list of RX frame buffers? | |
208 | */ | |
209 | u32 saved_rx_frame_index; | |
210 | ||
211 | /** | |
212 | * This field specifies the data necessary to manage the sub-state | |
213 | * machine executed while in the SCI_BASE_REQUEST_STATE_STARTED state. | |
214 | */ | |
215 | struct sci_base_state_machine started_substate_machine; | |
216 | ||
217 | /** | |
218 | * This field specifies the current state handlers in place for this | |
219 | * IO Request object. This field is updated each time the request | |
220 | * changes state. | |
221 | */ | |
222 | const struct scic_sds_io_request_state_handler *state_handlers; | |
223 | ||
224 | /** | |
225 | * This field in the recorded device sequence for the io request. This is | |
226 | * recorded during the build operation and is compared in the start | |
227 | * operation. If the sequence is different then there was a change of | |
228 | * devices from the build to start operations. | |
229 | */ | |
230 | u8 device_sequence; | |
231 | ||
232 | }; | |
233 | ||
234 | ||
235 | typedef enum sci_status | |
236 | (*scic_sds_io_request_frame_handler_t)(struct scic_sds_request *req, u32 frame); | |
237 | ||
238 | typedef enum sci_status | |
239 | (*scic_sds_io_request_event_handler_t)(struct scic_sds_request *req, u32 event); | |
240 | ||
241 | typedef enum sci_status | |
242 | (*scic_sds_io_request_task_completion_handler_t)(struct scic_sds_request *req, u32 completion_code); | |
243 | ||
244 | /** | |
245 | * struct scic_sds_io_request_state_handler - This is the SDS core definition | |
246 | * of the state handlers. | |
247 | * | |
248 | * | |
249 | */ | |
250 | struct scic_sds_io_request_state_handler { | |
251 | struct sci_base_request_state_handler parent; | |
252 | ||
253 | scic_sds_io_request_task_completion_handler_t tc_completion_handler; | |
254 | scic_sds_io_request_event_handler_t event_handler; | |
255 | scic_sds_io_request_frame_handler_t frame_handler; | |
256 | ||
257 | }; | |
258 | ||
6f231dda | 259 | extern const struct sci_base_state scic_sds_io_request_started_task_mgmt_substate_table[]; |
6f231dda DW |
260 | |
261 | /** | |
262 | * | |
263 | * | |
264 | * This macro returns the maximum number of SGL element paris that we will | |
265 | * support in a single IO request. | |
266 | */ | |
267 | #define SCU_MAX_SGL_ELEMENT_PAIRS ((SCU_IO_REQUEST_SGE_COUNT + 1) / 2) | |
268 | ||
269 | /** | |
270 | * scic_sds_request_get_controller() - | |
271 | * | |
272 | * This macro will return the controller for this io request object | |
273 | */ | |
274 | #define scic_sds_request_get_controller(this_request) \ | |
275 | ((this_request)->owning_controller) | |
276 | ||
277 | /** | |
278 | * scic_sds_request_get_device() - | |
279 | * | |
280 | * This macro will return the device for this io request object | |
281 | */ | |
282 | #define scic_sds_request_get_device(this_request) \ | |
283 | ((this_request)->target_device) | |
284 | ||
285 | /** | |
286 | * scic_sds_request_get_port() - | |
287 | * | |
288 | * This macro will return the port for this io request object | |
289 | */ | |
290 | #define scic_sds_request_get_port(this_request) \ | |
291 | scic_sds_remote_device_get_port(scic_sds_request_get_device(this_request)) | |
292 | ||
293 | /** | |
294 | * scic_sds_request_get_post_context() - | |
295 | * | |
296 | * This macro returns the constructed post context result for the io request. | |
297 | */ | |
298 | #define scic_sds_request_get_post_context(this_request) \ | |
299 | ((this_request)->post_context) | |
300 | ||
301 | /** | |
302 | * scic_sds_request_get_task_context() - | |
303 | * | |
304 | * This is a helper macro to return the os handle for this request object. | |
305 | */ | |
306 | #define scic_sds_request_get_task_context(request) \ | |
307 | ((request)->task_context_buffer) | |
308 | ||
6f231dda DW |
309 | /** |
310 | * scic_sds_request_set_status() - | |
311 | * | |
312 | * This macro will set the scu hardware status and sci request completion | |
313 | * status for an io request. | |
314 | */ | |
315 | #define scic_sds_request_set_status(request, scu_status_code, sci_status_code) \ | |
316 | { \ | |
317 | (request)->scu_status = (scu_status_code); \ | |
318 | (request)->sci_status = (sci_status_code); \ | |
319 | } | |
320 | ||
321 | #define scic_sds_request_complete(a_request) \ | |
322 | ((a_request)->state_handlers->parent.complete_handler(&(a_request)->parent)) | |
323 | ||
324 | ||
325 | ||
326 | ||
327 | /** | |
328 | * scic_sds_io_request_tc_completion() - | |
329 | * | |
330 | * This macro invokes the core state task completion handler for the | |
331 | * SCIC_SDS_IO_REQUEST_T object. | |
332 | */ | |
333 | #define scic_sds_io_request_tc_completion(this_request, completion_code) \ | |
334 | { \ | |
335 | if (this_request->parent.state_machine.current_state_id \ | |
336 | == SCI_BASE_REQUEST_STATE_STARTED \ | |
337 | && this_request->has_started_substate_machine \ | |
338 | == false) \ | |
339 | scic_sds_request_started_state_tc_completion_handler(this_request, completion_code); \ | |
340 | else \ | |
341 | this_request->state_handlers->tc_completion_handler(this_request, completion_code); \ | |
342 | } | |
343 | ||
344 | /** | |
345 | * SCU_SGL_ZERO() - | |
346 | * | |
347 | * This macro zeros the hardware SGL element data | |
348 | */ | |
349 | #define SCU_SGL_ZERO(scu_sge) \ | |
350 | { \ | |
351 | (scu_sge).length = 0; \ | |
352 | (scu_sge).address_lower = 0; \ | |
353 | (scu_sge).address_upper = 0; \ | |
354 | (scu_sge).address_modifier = 0; \ | |
355 | } | |
356 | ||
357 | /** | |
358 | * SCU_SGL_COPY() - | |
359 | * | |
360 | * This macro copys the SGL Element data from the host os to the hardware SGL | |
361 | * elment data | |
362 | */ | |
6389a775 | 363 | #define SCU_SGL_COPY(scu_sge, os_sge) \ |
6f231dda | 364 | { \ |
6389a775 | 365 | (scu_sge).length = sg_dma_len(sg); \ |
6f231dda | 366 | (scu_sge).address_upper = \ |
6389a775 | 367 | upper_32_bits(sg_dma_address(sg)); \ |
6f231dda | 368 | (scu_sge).address_lower = \ |
6389a775 | 369 | lower_32_bits(sg_dma_address(sg)); \ |
6f231dda DW |
370 | (scu_sge).address_modifier = 0; \ |
371 | } | |
372 | ||
103a00c2 DJ |
373 | /** |
374 | * scic_sds_request_get_user_request() - | |
375 | * | |
376 | * This is a helper macro to return the os handle for this request object. | |
377 | */ | |
378 | #define scic_sds_request_get_user_request(request) \ | |
379 | ((request)->user_request) | |
380 | ||
6f231dda DW |
381 | /* |
382 | * ***************************************************************************** | |
383 | * * CORE REQUEST PROTOTYPES | |
384 | * ***************************************************************************** */ | |
385 | ||
386 | void scic_sds_request_build_sgl( | |
387 | struct scic_sds_request *this_request); | |
388 | ||
389 | ||
390 | ||
391 | void scic_sds_stp_request_assign_buffers( | |
392 | struct scic_sds_request *this_request); | |
393 | ||
394 | void scic_sds_smp_request_assign_buffers( | |
395 | struct scic_sds_request *this_request); | |
396 | ||
397 | /* --------------------------------------------------------------------------- */ | |
398 | ||
399 | enum sci_status scic_sds_request_start( | |
400 | struct scic_sds_request *this_request); | |
401 | ||
402 | enum sci_status scic_sds_io_request_terminate( | |
403 | struct scic_sds_request *this_request); | |
404 | ||
405 | enum sci_status scic_sds_io_request_complete( | |
406 | struct scic_sds_request *this_request); | |
407 | ||
408 | void scic_sds_io_request_copy_response( | |
409 | struct scic_sds_request *this_request); | |
410 | ||
411 | enum sci_status scic_sds_io_request_event_handler( | |
412 | struct scic_sds_request *this_request, | |
413 | u32 event_code); | |
414 | ||
415 | enum sci_status scic_sds_io_request_frame_handler( | |
416 | struct scic_sds_request *this_request, | |
417 | u32 frame_index); | |
418 | ||
419 | ||
420 | enum sci_status scic_sds_task_request_terminate( | |
421 | struct scic_sds_request *this_request); | |
422 | ||
423 | /* | |
424 | * ***************************************************************************** | |
425 | * * DEFAULT STATE HANDLERS | |
426 | * ***************************************************************************** */ | |
427 | ||
428 | enum sci_status scic_sds_request_default_start_handler( | |
429 | struct sci_base_request *this_request); | |
430 | ||
431 | ||
432 | enum sci_status scic_sds_request_default_complete_handler( | |
433 | struct sci_base_request *this_request); | |
434 | ||
435 | enum sci_status scic_sds_request_default_destruct_handler( | |
436 | struct sci_base_request *this_request); | |
437 | ||
438 | enum sci_status scic_sds_request_default_tc_completion_handler( | |
439 | struct scic_sds_request *this_request, | |
440 | u32 completion_code); | |
441 | ||
442 | enum sci_status scic_sds_request_default_event_handler( | |
443 | struct scic_sds_request *this_request, | |
444 | u32 event_code); | |
445 | ||
446 | enum sci_status scic_sds_request_default_frame_handler( | |
447 | struct scic_sds_request *this_request, | |
448 | u32 frame_index); | |
449 | ||
450 | /* | |
451 | * ***************************************************************************** | |
452 | * * STARTED STATE HANDLERS | |
453 | * ***************************************************************************** */ | |
454 | ||
455 | enum sci_status scic_sds_request_started_state_abort_handler( | |
456 | struct sci_base_request *this_request); | |
457 | ||
458 | enum sci_status scic_sds_request_started_state_tc_completion_handler( | |
459 | struct scic_sds_request *this_request, | |
460 | u32 completion_code); | |
461 | ||
462 | #endif /* _SCIC_SDS_IO_REQUEST_H_ */ |