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  */
84 static
85 SCI_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  */
108 static
109 SCI_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  */
136 static
137 SCI_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  */
162 static
163 SCI_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  */
190 static
191 SCI_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  */
232 static
233 SCI_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  */
259 static
260 SCI_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  */
287 static
288 SCI_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  */
315 static
316 SCI_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  */
343 static
344 SCI_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 
361 SCI_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