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  */
88 SCI_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  */
107 SCI_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  */
134 static
135 SCI_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  */
160 static
161 SCI_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  */
188 static
189 SCI_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  */
221 static
222 SCI_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  */
247 static
248 SCI_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  */
274 static
275 SCI_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  */
302 static
303 SCI_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  */
330 SCI_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  */
357 SCI_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 
374 SCI_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