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 | ||
6f231dda | 59 | #include "scic_io_request.h" |
38aa74eb | 60 | #include "sci_base_state_machine.h" |
6f231dda | 61 | #include "scu_task_context.h" |
827a84d4 | 62 | #include "scic_sds_stp_request.h" |
0d84366f | 63 | #include "scu_constants.h" |
6f231dda DW |
64 | |
65 | struct scic_sds_controller; | |
66 | struct scic_sds_remote_device; | |
67 | struct scic_sds_io_request_state_handler; | |
68 | ||
69 | /** | |
de728b7d | 70 | * enum _scic_sds_io_request_started_task_mgmt_substates - This enumeration |
6f231dda DW |
71 | * depicts all of the substates for a task management request to be |
72 | * performed in the STARTED super-state. | |
73 | * | |
74 | * | |
75 | */ | |
76 | enum scic_sds_raw_request_started_task_mgmt_substates { | |
77 | /** | |
78 | * The AWAIT_TC_COMPLETION sub-state indicates that the started raw | |
79 | * task management request is waiting for the transmission of the | |
80 | * initial frame (i.e. command, task, etc.). | |
81 | */ | |
82 | SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_COMPLETION, | |
83 | ||
84 | /** | |
85 | * This sub-state indicates that the started task management request | |
86 | * is waiting for the reception of an unsolicited frame | |
87 | * (i.e. response IU). | |
88 | */ | |
89 | SCIC_SDS_IO_REQUEST_STARTED_TASK_MGMT_SUBSTATE_AWAIT_TC_RESPONSE, | |
90 | }; | |
91 | ||
92 | ||
93 | /** | |
de728b7d | 94 | * enum _scic_sds_smp_request_started_substates - This enumeration depicts all |
6f231dda DW |
95 | * of the substates for a SMP request to be performed in the STARTED |
96 | * super-state. | |
97 | * | |
98 | * | |
99 | */ | |
100 | enum scic_sds_smp_request_started_substates { | |
101 | /** | |
102 | * This sub-state indicates that the started task management request | |
103 | * is waiting for the reception of an unsolicited frame | |
104 | * (i.e. response IU). | |
105 | */ | |
106 | SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE, | |
107 | ||
108 | /** | |
109 | * The AWAIT_TC_COMPLETION sub-state indicates that the started SMP request is | |
110 | * waiting for the transmission of the initial frame (i.e. command, task, etc.). | |
111 | */ | |
112 | SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION, | |
113 | }; | |
114 | ||
890cae9b | 115 | struct isci_request; |
6f231dda | 116 | /** |
de728b7d | 117 | * struct scic_sds_request - This structure contains or references all of |
6f231dda DW |
118 | * the data necessary to process a task management or normal IO request. |
119 | * | |
120 | * | |
121 | */ | |
122 | struct scic_sds_request { | |
123 | /** | |
890cae9b | 124 | * The field specifies that the peer object for the request object. |
6f231dda | 125 | */ |
890cae9b | 126 | struct isci_request *ireq; |
38aa74eb CH |
127 | |
128 | /** | |
129 | * This field contains the information for the base request state machine. | |
130 | */ | |
131 | struct sci_base_state_machine state_machine; | |
6f231dda DW |
132 | |
133 | void *user_request; | |
134 | ||
135 | /** | |
136 | * This field simply points to the controller to which this IO request | |
137 | * is associated. | |
138 | */ | |
139 | struct scic_sds_controller *owning_controller; | |
140 | ||
141 | /** | |
142 | * This field simply points to the remote device to which this IO request | |
143 | * is associated. | |
144 | */ | |
145 | struct scic_sds_remote_device *target_device; | |
146 | ||
147 | /** | |
148 | * This field is utilized to determine if the SCI user is managing | |
149 | * the IO tag for this request or if the core is managing it. | |
150 | */ | |
151 | bool was_tag_assigned_by_user; | |
152 | ||
153 | /** | |
154 | * This field indicates the IO tag for this request. The IO tag is | |
155 | * comprised of the task_index and a sequence count. The sequence count | |
156 | * is utilized to help identify tasks from one life to another. | |
157 | */ | |
158 | u16 io_tag; | |
159 | ||
160 | /** | |
161 | * This field specifies the protocol being utilized for this | |
162 | * IO request. | |
163 | */ | |
164 | SCIC_TRANSPORT_PROTOCOL protocol; | |
165 | ||
166 | /** | |
167 | * This field indicates the completion status taken from the SCUs | |
168 | * completion code. It indicates the completion result for the SCU hardware. | |
169 | */ | |
170 | u32 scu_status; | |
171 | ||
172 | /** | |
173 | * This field indicates the completion status returned to the SCI user. It | |
174 | * indicates the users view of the io request completion. | |
175 | */ | |
176 | u32 sci_status; | |
177 | ||
178 | /** | |
179 | * This field contains the value to be utilized when posting (e.g. Post_TC, | |
180 | * Post_TC_Abort) this request to the silicon. | |
181 | */ | |
182 | u32 post_context; | |
183 | ||
184 | void *command_buffer; | |
185 | void *response_buffer; | |
186 | struct scu_task_context *task_context_buffer; | |
26298264 | 187 | struct scu_task_context tc ____cacheline_aligned; |
0d84366f DW |
188 | |
189 | /* could be larger with sg chaining */ | |
190 | #define SCU_SGL_SIZE ((SCU_IO_REQUEST_SGE_COUNT + 1) / 2) | |
191 | struct scu_sgl_element_pair sg_table[SCU_SGL_SIZE] __attribute__ ((aligned(32))); | |
6f231dda DW |
192 | |
193 | /** | |
194 | * This field indicates if this request is a task management request or | |
195 | * normal IO request. | |
196 | */ | |
197 | bool is_task_management_request; | |
198 | ||
199 | /** | |
200 | * This field indicates that this request contains an initialized started | |
201 | * substate machine. | |
202 | */ | |
203 | bool has_started_substate_machine; | |
204 | ||
205 | /** | |
206 | * This field is a pointer to the stored rx frame data. It is used in STP | |
207 | * internal requests and SMP response frames. If this field is non-NULL the | |
208 | * saved frame must be released on IO request completion. | |
209 | * | |
210 | * @todo In the future do we want to keep a list of RX frame buffers? | |
211 | */ | |
212 | u32 saved_rx_frame_index; | |
213 | ||
214 | /** | |
215 | * This field specifies the data necessary to manage the sub-state | |
216 | * machine executed while in the SCI_BASE_REQUEST_STATE_STARTED state. | |
217 | */ | |
218 | struct sci_base_state_machine started_substate_machine; | |
219 | ||
220 | /** | |
221 | * This field specifies the current state handlers in place for this | |
222 | * IO Request object. This field is updated each time the request | |
223 | * changes state. | |
224 | */ | |
225 | const struct scic_sds_io_request_state_handler *state_handlers; | |
226 | ||
227 | /** | |
228 | * This field in the recorded device sequence for the io request. This is | |
229 | * recorded during the build operation and is compared in the start | |
230 | * operation. If the sequence is different then there was a change of | |
231 | * devices from the build to start operations. | |
232 | */ | |
233 | u8 device_sequence; | |
234 | ||
827a84d4 DW |
235 | struct { |
236 | struct scic_sds_stp_request req; | |
237 | } stp; | |
6f231dda DW |
238 | }; |
239 | ||
827a84d4 DW |
240 | static inline struct scic_sds_request *to_sci_req(struct scic_sds_stp_request *stp_req) |
241 | { | |
242 | struct scic_sds_request *sci_req; | |
243 | ||
244 | sci_req = container_of(stp_req, typeof(*sci_req), stp.req); | |
245 | return sci_req; | |
246 | } | |
247 | ||
38aa74eb CH |
248 | /** |
249 | * enum sci_base_request_states - This enumeration depicts all the states for | |
250 | * the common request state machine. | |
251 | * | |
252 | * | |
253 | */ | |
254 | enum sci_base_request_states { | |
255 | /** | |
256 | * Simply the initial state for the base request state machine. | |
257 | */ | |
258 | SCI_BASE_REQUEST_STATE_INITIAL, | |
259 | ||
260 | /** | |
261 | * This state indicates that the request has been constructed. This state | |
262 | * is entered from the INITIAL state. | |
263 | */ | |
264 | SCI_BASE_REQUEST_STATE_CONSTRUCTED, | |
265 | ||
266 | /** | |
267 | * This state indicates that the request has been started. This state is | |
268 | * entered from the CONSTRUCTED state. | |
269 | */ | |
270 | SCI_BASE_REQUEST_STATE_STARTED, | |
271 | ||
272 | /** | |
273 | * This state indicates that the request has completed. | |
274 | * This state is entered from the STARTED state. This state is entered from | |
275 | * the ABORTING state. | |
276 | */ | |
277 | SCI_BASE_REQUEST_STATE_COMPLETED, | |
6f231dda | 278 | |
38aa74eb CH |
279 | /** |
280 | * This state indicates that the request is in the process of being | |
281 | * terminated/aborted. | |
282 | * This state is entered from the CONSTRUCTED state. | |
283 | * This state is entered from the STARTED state. | |
284 | */ | |
285 | SCI_BASE_REQUEST_STATE_ABORTING, | |
6f231dda | 286 | |
38aa74eb CH |
287 | /** |
288 | * Simply the final state for the base request state machine. | |
289 | */ | |
290 | SCI_BASE_REQUEST_STATE_FINAL, | |
291 | }; | |
6f231dda | 292 | |
38aa74eb CH |
293 | typedef enum sci_status (*scic_sds_io_request_handler_t) |
294 | (struct scic_sds_request *request); | |
295 | typedef enum sci_status (*scic_sds_io_request_frame_handler_t) | |
296 | (struct scic_sds_request *req, u32 frame); | |
297 | typedef enum sci_status (*scic_sds_io_request_event_handler_t) | |
298 | (struct scic_sds_request *req, u32 event); | |
299 | typedef enum sci_status (*scic_sds_io_request_task_completion_handler_t) | |
300 | (struct scic_sds_request *req, u32 completion_code); | |
6f231dda DW |
301 | |
302 | /** | |
303 | * struct scic_sds_io_request_state_handler - This is the SDS core definition | |
304 | * of the state handlers. | |
305 | * | |
306 | * | |
307 | */ | |
308 | struct scic_sds_io_request_state_handler { | |
38aa74eb CH |
309 | /** |
310 | * The start_handler specifies the method invoked when a user attempts to | |
311 | * start a request. | |
312 | */ | |
313 | scic_sds_io_request_handler_t start_handler; | |
314 | ||
315 | /** | |
316 | * The abort_handler specifies the method invoked when a user attempts to | |
317 | * abort a request. | |
318 | */ | |
319 | scic_sds_io_request_handler_t abort_handler; | |
320 | ||
321 | /** | |
322 | * The complete_handler specifies the method invoked when a user attempts to | |
323 | * complete a request. | |
324 | */ | |
325 | scic_sds_io_request_handler_t complete_handler; | |
326 | ||
6f231dda DW |
327 | scic_sds_io_request_task_completion_handler_t tc_completion_handler; |
328 | scic_sds_io_request_event_handler_t event_handler; | |
329 | scic_sds_io_request_frame_handler_t frame_handler; | |
330 | ||
331 | }; | |
332 | ||
6f231dda | 333 | extern const struct sci_base_state scic_sds_io_request_started_task_mgmt_substate_table[]; |
6f231dda | 334 | |
6f231dda DW |
335 | /** |
336 | * scic_sds_request_get_controller() - | |
337 | * | |
338 | * This macro will return the controller for this io request object | |
339 | */ | |
e2023b87 DJ |
340 | #define scic_sds_request_get_controller(sci_req) \ |
341 | ((sci_req)->owning_controller) | |
6f231dda DW |
342 | |
343 | /** | |
344 | * scic_sds_request_get_device() - | |
345 | * | |
346 | * This macro will return the device for this io request object | |
347 | */ | |
e2023b87 DJ |
348 | #define scic_sds_request_get_device(sci_req) \ |
349 | ((sci_req)->target_device) | |
6f231dda DW |
350 | |
351 | /** | |
352 | * scic_sds_request_get_port() - | |
353 | * | |
354 | * This macro will return the port for this io request object | |
355 | */ | |
e2023b87 DJ |
356 | #define scic_sds_request_get_port(sci_req) \ |
357 | scic_sds_remote_device_get_port(scic_sds_request_get_device(sci_req)) | |
6f231dda DW |
358 | |
359 | /** | |
360 | * scic_sds_request_get_post_context() - | |
361 | * | |
362 | * This macro returns the constructed post context result for the io request. | |
363 | */ | |
e2023b87 DJ |
364 | #define scic_sds_request_get_post_context(sci_req) \ |
365 | ((sci_req)->post_context) | |
6f231dda DW |
366 | |
367 | /** | |
368 | * scic_sds_request_get_task_context() - | |
369 | * | |
370 | * This is a helper macro to return the os handle for this request object. | |
371 | */ | |
372 | #define scic_sds_request_get_task_context(request) \ | |
373 | ((request)->task_context_buffer) | |
374 | ||
6f231dda DW |
375 | /** |
376 | * scic_sds_request_set_status() - | |
377 | * | |
378 | * This macro will set the scu hardware status and sci request completion | |
379 | * status for an io request. | |
380 | */ | |
381 | #define scic_sds_request_set_status(request, scu_status_code, sci_status_code) \ | |
382 | { \ | |
383 | (request)->scu_status = (scu_status_code); \ | |
384 | (request)->sci_status = (sci_status_code); \ | |
385 | } | |
386 | ||
387 | #define scic_sds_request_complete(a_request) \ | |
38aa74eb | 388 | ((a_request)->state_handlers->complete_handler(a_request)) |
6f231dda DW |
389 | |
390 | ||
524b5f72 CH |
391 | extern enum sci_status |
392 | scic_sds_io_request_tc_completion(struct scic_sds_request *request, u32 completion_code); | |
6f231dda DW |
393 | |
394 | /** | |
395 | * SCU_SGL_ZERO() - | |
396 | * | |
397 | * This macro zeros the hardware SGL element data | |
398 | */ | |
399 | #define SCU_SGL_ZERO(scu_sge) \ | |
400 | { \ | |
401 | (scu_sge).length = 0; \ | |
402 | (scu_sge).address_lower = 0; \ | |
403 | (scu_sge).address_upper = 0; \ | |
404 | (scu_sge).address_modifier = 0; \ | |
405 | } | |
406 | ||
407 | /** | |
408 | * SCU_SGL_COPY() - | |
409 | * | |
410 | * This macro copys the SGL Element data from the host os to the hardware SGL | |
411 | * elment data | |
412 | */ | |
6389a775 | 413 | #define SCU_SGL_COPY(scu_sge, os_sge) \ |
6f231dda | 414 | { \ |
6389a775 | 415 | (scu_sge).length = sg_dma_len(sg); \ |
6f231dda | 416 | (scu_sge).address_upper = \ |
6389a775 | 417 | upper_32_bits(sg_dma_address(sg)); \ |
6f231dda | 418 | (scu_sge).address_lower = \ |
6389a775 | 419 | lower_32_bits(sg_dma_address(sg)); \ |
6f231dda DW |
420 | (scu_sge).address_modifier = 0; \ |
421 | } | |
422 | ||
103a00c2 DJ |
423 | /** |
424 | * scic_sds_request_get_user_request() - | |
425 | * | |
426 | * This is a helper macro to return the os handle for this request object. | |
427 | */ | |
428 | #define scic_sds_request_get_user_request(request) \ | |
429 | ((request)->user_request) | |
430 | ||
6f231dda DW |
431 | /* |
432 | * ***************************************************************************** | |
433 | * * CORE REQUEST PROTOTYPES | |
434 | * ***************************************************************************** */ | |
435 | ||
436 | void scic_sds_request_build_sgl( | |
e2023b87 | 437 | struct scic_sds_request *sci_req); |
6f231dda DW |
438 | |
439 | ||
440 | ||
441 | void scic_sds_stp_request_assign_buffers( | |
e2023b87 | 442 | struct scic_sds_request *sci_req); |
6f231dda DW |
443 | |
444 | void scic_sds_smp_request_assign_buffers( | |
e2023b87 | 445 | struct scic_sds_request *sci_req); |
6f231dda DW |
446 | |
447 | /* --------------------------------------------------------------------------- */ | |
448 | ||
449 | enum sci_status scic_sds_request_start( | |
e2023b87 | 450 | struct scic_sds_request *sci_req); |
6f231dda DW |
451 | |
452 | enum sci_status scic_sds_io_request_terminate( | |
e2023b87 | 453 | struct scic_sds_request *sci_req); |
6f231dda DW |
454 | |
455 | enum sci_status scic_sds_io_request_complete( | |
e2023b87 | 456 | struct scic_sds_request *sci_req); |
6f231dda DW |
457 | |
458 | void scic_sds_io_request_copy_response( | |
e2023b87 | 459 | struct scic_sds_request *sci_req); |
6f231dda DW |
460 | |
461 | enum sci_status scic_sds_io_request_event_handler( | |
e2023b87 | 462 | struct scic_sds_request *sci_req, |
6f231dda DW |
463 | u32 event_code); |
464 | ||
465 | enum sci_status scic_sds_io_request_frame_handler( | |
e2023b87 | 466 | struct scic_sds_request *sci_req, |
6f231dda DW |
467 | u32 frame_index); |
468 | ||
469 | ||
470 | enum sci_status scic_sds_task_request_terminate( | |
e2023b87 | 471 | struct scic_sds_request *sci_req); |
6f231dda | 472 | |
6f231dda DW |
473 | /* |
474 | * ***************************************************************************** | |
475 | * * STARTED STATE HANDLERS | |
476 | * ***************************************************************************** */ | |
477 | ||
478 | enum sci_status scic_sds_request_started_state_abort_handler( | |
e2023b87 | 479 | struct scic_sds_request *sci_req); |
6f231dda DW |
480 | |
481 | enum sci_status scic_sds_request_started_state_tc_completion_handler( | |
e2023b87 | 482 | struct scic_sds_request *sci_req, |
6f231dda DW |
483 | u32 completion_code); |
484 | ||
485 | #endif /* _SCIC_SDS_IO_REQUEST_H_ */ |