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