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 /**
57 * @file
58 *
59 * @brief This file contains all of the SCIF_SAS_TASK_REQUEST object
60 * state entrance and exit method implementations.
61 */
62
63 #include <dev/isci/scil/scif_sas_task_request.h>
64
65 //******************************************************************************
66 //* P R O T E C T E D M E T H O D S
67 //******************************************************************************
68
69 /**
70 * @brief This method implements the actions taken when entering the
71 * INITIAL state.
72 *
73 * @param[in] object This parameter specifies the base object for which
74 * the state transition is occurring. This is cast into a
75 * SCIF_SAS_TASK_REQUEST object in the method implementation.
76 *
77 * @return none
78 */
79 static
scif_sas_task_request_initial_state_enter(SCI_BASE_OBJECT_T * object)80 void scif_sas_task_request_initial_state_enter(
81 SCI_BASE_OBJECT_T *object
82 )
83 {
84 SCIF_SAS_TASK_REQUEST_T * fw_task = (SCIF_SAS_TASK_REQUEST_T *)object;
85
86 SET_STATE_HANDLER(
87 &fw_task->parent,
88 scif_sas_task_request_state_handler_table,
89 SCI_BASE_REQUEST_STATE_INITIAL
90 );
91
92 // Initial state is a transitional state to the constructed state
93 sci_base_state_machine_change_state(
94 &fw_task->parent.parent.state_machine, SCI_BASE_REQUEST_STATE_CONSTRUCTED
95 );
96 }
97
98 /**
99 * @brief This method implements the actions taken when entering the
100 * CONSTRUCTED state.
101 *
102 * @param[in] object This parameter specifies the base object for which
103 * the state transition is occurring. This is cast into a
104 * SCIF_SAS_TASK_REQUEST object in the method implementation.
105 *
106 * @return none
107 */
108 static
scif_sas_task_request_constructed_state_enter(SCI_BASE_OBJECT_T * object)109 void scif_sas_task_request_constructed_state_enter(
110 SCI_BASE_OBJECT_T *object
111 )
112 {
113 SCIF_SAS_TASK_REQUEST_T * fw_task = (SCIF_SAS_TASK_REQUEST_T *)object;
114
115 SET_STATE_HANDLER(
116 &fw_task->parent,
117 scif_sas_task_request_state_handler_table,
118 SCI_BASE_REQUEST_STATE_CONSTRUCTED
119 );
120 }
121
122 /**
123 * @brief This method implements the actions taken when entering the
124 * STARTED state.
125 *
126 * @param[in] object This parameter specifies the base object for which
127 * the state transition is occurring. This is cast into a
128 * SCIF_SAS_TASK_REQUEST object in the method implementation.
129 *
130 * @return none
131 */
132 static
scif_sas_task_request_started_state_enter(SCI_BASE_OBJECT_T * object)133 void scif_sas_task_request_started_state_enter(
134 SCI_BASE_OBJECT_T *object
135 )
136 {
137 SCIF_SAS_TASK_REQUEST_T * fw_task = (SCIF_SAS_TASK_REQUEST_T *)object;
138
139 SET_STATE_HANDLER(
140 &fw_task->parent,
141 scif_sas_task_request_state_handler_table,
142 SCI_BASE_REQUEST_STATE_STARTED
143 );
144
145 // Increment the affected request count to include the task performing
146 // the task management to ensure we don't complete the task request until
147 // all terminations and the task itself have completed.
148 fw_task->affected_request_count++;
149 }
150
151 /**
152 * @brief This method implements the actions taken when entering the
153 * COMPLETED state.
154 *
155 * @param[in] object This parameter specifies the base object for which
156 * the state transition is occurring. This is cast into a
157 * SCIF_SAS_TASK_REQUEST object in the method implementation.
158 *
159 * @return none
160 */
161 static
scif_sas_task_request_completed_state_enter(SCI_BASE_OBJECT_T * object)162 void scif_sas_task_request_completed_state_enter(
163 SCI_BASE_OBJECT_T *object
164 )
165 {
166 SCIF_SAS_TASK_REQUEST_T * fw_task = (SCIF_SAS_TASK_REQUEST_T *)object;
167
168 SET_STATE_HANDLER(
169 &fw_task->parent,
170 scif_sas_task_request_state_handler_table,
171 SCI_BASE_REQUEST_STATE_COMPLETED
172 );
173
174 // Check to see if the task management operation is now finished (i.e.
175 // all of the task terminations and the task management request are
176 // complete).
177 scif_sas_task_request_operation_complete(fw_task);
178 }
179
180 /**
181 * @brief This method implements the actions taken when entering the
182 * ABORTING state.
183 *
184 * @param[in] object This parameter specifies the base object for which
185 * the state transition is occurring. This is cast into a
186 * SCIF_SAS_TASK_REQUEST object in the method implementation.
187 *
188 * @return none
189 */
190 static
scif_sas_task_request_aborting_state_enter(SCI_BASE_OBJECT_T * object)191 void scif_sas_task_request_aborting_state_enter(
192 SCI_BASE_OBJECT_T *object
193 )
194 {
195 SCIF_SAS_TASK_REQUEST_T * fw_task = (SCIF_SAS_TASK_REQUEST_T *)object;
196
197 SET_STATE_HANDLER(
198 &fw_task->parent,
199 scif_sas_task_request_state_handler_table,
200 SCI_BASE_REQUEST_STATE_ABORTING
201 );
202
203 /// @todo Is terminating a previously outstanding task request right?
204 fw_task->parent.status = scif_sas_request_terminate_start(
205 &fw_task->parent, fw_task->parent.core_object
206 );
207 }
208
209 /**
210 * @brief This method implements the actions taken when exiting the
211 * ABORTING state.
212 *
213 * @param[in] object This parameter specifies the base object for which
214 * the state transition is occurring. This is cast into a
215 * SCIF_SAS_TASK_REQUEST object in the method implementation.
216 *
217 * @return none
218 */
219 static
scif_sas_task_request_aborting_state_exit(SCI_BASE_OBJECT_T * object)220 void scif_sas_task_request_aborting_state_exit(
221 SCI_BASE_OBJECT_T *object
222 )
223 {
224 SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T *)object;
225 scif_sas_request_terminate_complete(fw_request);
226 }
227
228 /**
229 * @brief This method implements the actions taken when entering the
230 * FINAL state.
231 *
232 * @param[in] object This parameter specifies the base object for which
233 * the state transition is occurring. This is cast into a
234 * SCIF_SAS_TASK_REQUEST object in the method implementation.
235 *
236 * @return none
237 */
238 static
scif_sas_task_request_final_state_enter(SCI_BASE_OBJECT_T * object)239 void scif_sas_task_request_final_state_enter(
240 SCI_BASE_OBJECT_T *object
241 )
242 {
243 SCIF_SAS_TASK_REQUEST_T * fw_task = (SCIF_SAS_TASK_REQUEST_T *)object;
244
245 SET_STATE_HANDLER(
246 &fw_task->parent,
247 scif_sas_task_request_state_handler_table,
248 SCI_BASE_REQUEST_STATE_FINAL
249 );
250 }
251
252
253 SCI_BASE_STATE_T
254 scif_sas_task_request_state_table[SCI_BASE_REQUEST_MAX_STATES] =
255 {
256 {
257 SCI_BASE_REQUEST_STATE_INITIAL,
258 scif_sas_task_request_initial_state_enter,
259 NULL
260 },
261 {
262 SCI_BASE_REQUEST_STATE_CONSTRUCTED,
263 scif_sas_task_request_constructed_state_enter,
264 NULL
265 },
266 {
267 SCI_BASE_REQUEST_STATE_STARTED,
268 scif_sas_task_request_started_state_enter,
269 NULL
270 },
271 {
272 SCI_BASE_REQUEST_STATE_COMPLETED,
273 scif_sas_task_request_completed_state_enter,
274 NULL
275 },
276 {
277 SCI_BASE_REQUEST_STATE_ABORTING,
278 scif_sas_task_request_aborting_state_enter,
279 scif_sas_task_request_aborting_state_exit
280 },
281 {
282 SCI_BASE_REQUEST_STATE_FINAL,
283 scif_sas_task_request_final_state_enter,
284 NULL
285 },
286 };
287
288