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