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 /**
57 * @file
58 *
59 * @brief This file contains all of the method implementations pertaining
60 * to the framework io request state handler methods.
61 */
62
63 #include <dev/isci/scil/scic_controller.h>
64 #include <dev/isci/scil/scif_sas_logger.h>
65 #include <dev/isci/scil/scif_sas_io_request.h>
66 #include <dev/isci/scil/scif_sas_remote_device.h>
67 #include <dev/isci/scil/scif_sas_domain.h>
68 #include <dev/isci/scil/scif_sas_controller.h>
69
70 //******************************************************************************
71 //* C O N S T R U C T E D H A N D L E R S
72 //******************************************************************************
73
74 /**
75 * @brief This method provides CONSTRUCTED state specific handling for
76 * when the user attempts to start the supplied IO request.
77 *
78 * @param[in] io_request This parameter specifies the IO request object
79 * to be started.
80 *
81 * @return This method returns a value indicating if the IO request was
82 * successfully started or not.
83 * @retval SCI_SUCCESS This return value indicates successful starting
84 * of the IO request.
85 */
scif_sas_io_request_constructed_start_handler(SCI_BASE_REQUEST_T * io_request)86 SCI_STATUS scif_sas_io_request_constructed_start_handler(
87 SCI_BASE_REQUEST_T * io_request
88 )
89 {
90 return SCI_SUCCESS;
91 }
92
93 /**
94 * @brief This method provides CONSTRUCTED state specific handling for
95 * when the user attempts to abort the supplied IO request.
96 *
97 * @param[in] io_request This parameter specifies the IO request object
98 * to be aborted.
99 *
100 * @return This method returns a value indicating if the IO request was
101 * successfully aborted or not.
102 * @retval SCI_SUCCESS This return value indicates successful aborting
103 * of the IO request.
104 */
scif_sas_io_request_constructed_abort_handler(SCI_BASE_REQUEST_T * io_request)105 SCI_STATUS scif_sas_io_request_constructed_abort_handler(
106 SCI_BASE_REQUEST_T * io_request
107 )
108 {
109 sci_base_state_machine_change_state(
110 &io_request->state_machine, SCI_BASE_REQUEST_STATE_COMPLETED
111 );
112
113 return SCI_SUCCESS;
114 }
115
116 //******************************************************************************
117 //* S T A R T E D H A N D L E R S
118 //******************************************************************************
119
120 /**
121 * @brief This method provides STARTED state specific handling for
122 * when the user attempts to abort the supplied IO request.
123 *
124 * @param[in] io_request This parameter specifies the IO request object
125 * to be aborted.
126 *
127 * @return This method returns a value indicating if the aborting the
128 * IO request was successfully started.
129 * @retval SCI_SUCCESS This return value indicates that the abort process
130 * began successfully.
131 */
132 static
scif_sas_io_request_started_abort_handler(SCI_BASE_REQUEST_T * io_request)133 SCI_STATUS scif_sas_io_request_started_abort_handler(
134 SCI_BASE_REQUEST_T * io_request
135 )
136 {
137 SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T *) io_request;
138
139 sci_base_state_machine_change_state(
140 &io_request->state_machine, SCI_BASE_REQUEST_STATE_ABORTING
141 );
142
143 return fw_request->status;
144 }
145
146 /**
147 * @brief This method provides STARTED state specific handling for
148 * when the user attempts to complete the supplied IO request.
149 *
150 * @param[in] io_request This parameter specifies the IO request object
151 * to be completed.
152 *
153 * @return This method returns a value indicating if the completion of the
154 * IO request was successful.
155 * @retval SCI_SUCCESS This return value indicates that the completion process
156 * was successful.
157 */
158 static
scif_sas_io_request_started_complete_handler(SCI_BASE_REQUEST_T * io_request)159 SCI_STATUS scif_sas_io_request_started_complete_handler(
160 SCI_BASE_REQUEST_T * io_request
161 )
162 {
163 sci_base_state_machine_change_state(
164 &io_request->state_machine, SCI_BASE_REQUEST_STATE_COMPLETED
165 );
166
167 return SCI_SUCCESS;
168 }
169
170 //******************************************************************************
171 //* C O M P L E T E D H A N D L E R S
172 //******************************************************************************
173
174 /**
175 * @brief This method provides COMPLETED state specific handling for
176 * when the user attempts to destruct the supplied IO request.
177 *
178 * @param[in] io_request This parameter specifies the IO request object
179 * to be destructed.
180 *
181 * @return This method returns a value indicating if the destruct
182 * operation was successful.
183 * @retval SCI_SUCCESS This return value indicates that the destruct
184 * was successful.
185 */
186 static
scif_sas_io_request_completed_destruct_handler(SCI_BASE_REQUEST_T * io_request)187 SCI_STATUS scif_sas_io_request_completed_destruct_handler(
188 SCI_BASE_REQUEST_T * io_request
189 )
190 {
191 sci_base_state_machine_change_state(
192 &io_request->state_machine, SCI_BASE_REQUEST_STATE_FINAL
193 );
194
195 sci_base_state_machine_logger_deinitialize(
196 &io_request->state_machine_logger,
197 &io_request->state_machine
198 );
199
200 return SCI_SUCCESS;
201 }
202
203 //******************************************************************************
204 //* A B O R T I N G H A N D L E R S
205 //******************************************************************************
206
207 /**
208 * @brief This method provides ABORTING state specific handlering for when the
209 * user attempts to abort the supplied IO request.
210 *
211 * @param[in] io_request This parameter specifies the IO request object
212 * to be completed.
213 *
214 * @return This method returns a value indicating if the completion
215 * operation was successful.
216 * @retval SCI_SUCCESS This return value indicates that the abort operation
217 * was successful.
218 */
219 static
scif_sas_io_request_aborting_abort_handler(SCI_BASE_REQUEST_T * io_request)220 SCI_STATUS scif_sas_io_request_aborting_abort_handler(
221 SCI_BASE_REQUEST_T * io_request
222 )
223 {
224 SCIF_SAS_IO_REQUEST_T * fw_request = (SCIF_SAS_IO_REQUEST_T *) io_request;
225
226 return scic_controller_terminate_request(
227 fw_request->parent.device->domain->controller->core_object,
228 fw_request->parent.device->core_object,
229 fw_request->parent.core_object
230 );
231 }
232
233 /**
234 * @brief This method provides ABORTING state specific handling for
235 * when the user attempts to complete the supplied IO request.
236 *
237 * @param[in] io_request This parameter specifies the IO request object
238 * to be completed.
239 *
240 * @return This method returns a value indicating if the completion
241 * operation was successful.
242 * @retval SCI_SUCCESS This return value indicates that the completion
243 * was successful.
244 */
245 static
scif_sas_io_request_aborting_complete_handler(SCI_BASE_REQUEST_T * io_request)246 SCI_STATUS scif_sas_io_request_aborting_complete_handler(
247 SCI_BASE_REQUEST_T * io_request
248 )
249 {
250 sci_base_state_machine_change_state(
251 &io_request->state_machine, SCI_BASE_REQUEST_STATE_COMPLETED
252 );
253
254 return SCI_SUCCESS;
255 }
256
257 //******************************************************************************
258 //* D E F A U L T H A N D L E R S
259 //******************************************************************************
260
261 /**
262 * @brief This method provides DEFAULT handling for when the user
263 * attempts to start the supplied IO request.
264 *
265 * @param[in] io_request This parameter specifies the IO request object
266 * to be started.
267 *
268 * @return This method returns an indication that the start operation is
269 * not allowed.
270 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
271 */
272 static
scif_sas_io_request_default_start_handler(SCI_BASE_REQUEST_T * io_request)273 SCI_STATUS scif_sas_io_request_default_start_handler(
274 SCI_BASE_REQUEST_T * io_request
275 )
276 {
277 SCIF_LOG_ERROR((
278 sci_base_object_get_logger((SCIF_SAS_IO_REQUEST_T *) io_request),
279 SCIF_LOG_OBJECT_IO_REQUEST,
280 "IoRequest:0x%x State:0x%x invalid state to start\n",
281 io_request,
282 sci_base_state_machine_get_state(
283 &((SCIF_SAS_IO_REQUEST_T *) io_request)->parent.parent.state_machine)
284 ));
285
286 return SCI_FAILURE_INVALID_STATE;
287 }
288
289 /**
290 * @brief This method provides DEFAULT handling for when the user
291 * attempts to abort the supplied IO request.
292 *
293 * @param[in] io_request This parameter specifies the IO request object
294 * to be aborted.
295 *
296 * @return This method returns an indication that the abort operation is
297 * not allowed.
298 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
299 */
300 static
scif_sas_io_request_default_abort_handler(SCI_BASE_REQUEST_T * io_request)301 SCI_STATUS scif_sas_io_request_default_abort_handler(
302 SCI_BASE_REQUEST_T * io_request
303 )
304 {
305 SCIF_LOG_ERROR((
306 sci_base_object_get_logger((SCIF_SAS_IO_REQUEST_T *) io_request),
307 SCIF_LOG_OBJECT_IO_REQUEST,
308 "IoRequest:0x%x State:0x%x invalid state to abort\n",
309 io_request,
310 sci_base_state_machine_get_state(
311 &((SCIF_SAS_IO_REQUEST_T *) io_request)->parent.parent.state_machine)
312 ));
313
314 return SCI_FAILURE_INVALID_STATE;
315 }
316
317 /**
318 * @brief This method provides DEFAULT handling for when the user
319 * attempts to complete the supplied IO request.
320 *
321 * @param[in] io_request This parameter specifies the IO request object
322 * to be completed.
323 *
324 * @return This method returns an indication that complete operation is
325 * not allowed.
326 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
327 */
scif_sas_io_request_default_complete_handler(SCI_BASE_REQUEST_T * io_request)328 SCI_STATUS scif_sas_io_request_default_complete_handler(
329 SCI_BASE_REQUEST_T * io_request
330 )
331 {
332 SCIF_LOG_ERROR((
333 sci_base_object_get_logger((SCIF_SAS_IO_REQUEST_T *) io_request),
334 SCIF_LOG_OBJECT_IO_REQUEST,
335 "IoRequest:0x%x State:0x%x invalid state to complete\n",
336 io_request,
337 sci_base_state_machine_get_state(
338 &((SCIF_SAS_IO_REQUEST_T *) io_request)->parent.parent.state_machine)
339 ));
340
341 return SCI_FAILURE_INVALID_STATE;
342 }
343
344 /**
345 * @brief This method provides DEFAULT handling for when the user
346 * attempts to destruct the supplied IO request.
347 *
348 * @param[in] io_request This parameter specifies the IO request object
349 * to be destructed.
350 *
351 * @return This method returns an indication that destruct operation is
352 * not allowed.
353 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
354 */
scif_sas_io_request_default_destruct_handler(SCI_BASE_REQUEST_T * io_request)355 SCI_STATUS scif_sas_io_request_default_destruct_handler(
356 SCI_BASE_REQUEST_T * io_request
357 )
358 {
359 SCIF_LOG_ERROR((
360 sci_base_object_get_logger((SCIF_SAS_IO_REQUEST_T *) io_request),
361 SCIF_LOG_OBJECT_IO_REQUEST,
362 "IoRequest:0x%x State:0x%x invalid state to destruct.\n",
363 io_request,
364 sci_base_state_machine_get_state(
365 &((SCIF_SAS_IO_REQUEST_T *) io_request)->parent.parent.state_machine)
366 ));
367
368 return SCI_FAILURE_INVALID_STATE;
369 }
370
371
372 SCI_BASE_REQUEST_STATE_HANDLER_T scif_sas_io_request_state_handler_table[] =
373 {
374 // SCI_BASE_REQUEST_STATE_INITIAL
375 {
376 scif_sas_io_request_default_start_handler,
377 scif_sas_io_request_default_abort_handler,
378 scif_sas_io_request_default_complete_handler,
379 scif_sas_io_request_default_destruct_handler
380 },
381 // SCI_BASE_REQUEST_STATE_CONSTRUCTED
382 {
383 scif_sas_io_request_constructed_start_handler,
384 scif_sas_io_request_constructed_abort_handler,
385 scif_sas_io_request_default_complete_handler,
386 scif_sas_io_request_default_destruct_handler
387 },
388 // SCI_BASE_REQUEST_STATE_STARTED
389 {
390 scif_sas_io_request_default_start_handler,
391 scif_sas_io_request_started_abort_handler,
392 scif_sas_io_request_started_complete_handler,
393 scif_sas_io_request_default_destruct_handler
394 },
395 // SCI_BASE_REQUEST_STATE_COMPLETED
396 {
397 scif_sas_io_request_default_start_handler,
398 scif_sas_io_request_default_abort_handler,
399 scif_sas_io_request_default_complete_handler,
400 scif_sas_io_request_completed_destruct_handler
401 },
402 // SCI_BASE_REQUEST_STATE_ABORTING
403 {
404 scif_sas_io_request_default_start_handler,
405 scif_sas_io_request_aborting_abort_handler,
406 scif_sas_io_request_aborting_complete_handler,
407 scif_sas_io_request_default_destruct_handler
408 },
409 // SCI_BASE_REQUEST_STATE_FINAL
410 {
411 scif_sas_io_request_default_start_handler,
412 scif_sas_io_request_default_abort_handler,
413 scif_sas_io_request_default_complete_handler,
414 scif_sas_io_request_default_destruct_handler
415 },
416 };
417
418