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