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 entrance and exit methods for each
62 * of the controller states defined by the SCI_BASE_CONTROLLER state
63 * machine.
64 */
65
66 #include <dev/isci/scil/scic_controller.h>
67
68 #include <dev/isci/scil/scif_sas_logger.h>
69 #include <dev/isci/scil/scif_sas_controller.h>
70
71 //******************************************************************************
72 //* P R O T E C T E D M E T H O D S
73 //******************************************************************************
74
75 /**
76 * @brief This method implements the actions taken when entering the
77 * INITIAL state.
78 *
79 * @param[in] object This parameter specifies the base object for which
80 * the state transition is occurring. This is cast into a
81 * SCIF_SAS_CONTROLLER object in the method implementation.
82 *
83 * @return none
84 */
85 static
86 void scif_sas_controller_initial_state_enter(
87 SCI_BASE_OBJECT_T * object
88 )
89 {
90 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object;
91
92 SET_STATE_HANDLER(
93 fw_controller,
94 scif_sas_controller_state_handler_table,
95 SCI_BASE_CONTROLLER_STATE_INITIAL
96 );
97 }
98
99 /**
100 * @brief This method implements the actions taken when entering the
101 * RESET state.
102 *
103 * @param[in] object This parameter specifies the base object for which
104 * the state transition is occurring. This is cast into a
105 * SCIF_SAS_CONTROLLER object in the method implementation.
106 *
107 * @return none
108 */
109 static
110 void scif_sas_controller_reset_state_enter(
111 SCI_BASE_OBJECT_T * object
112 )
113 {
114 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object;
115 U8 index;
116 U16 smp_phy_index;
117
118 SET_STATE_HANDLER(
119 fw_controller,
120 scif_sas_controller_state_handler_table,
121 SCI_BASE_CONTROLLER_STATE_RESET
122 );
123
124 scif_sas_high_priority_request_queue_construct(
125 &fw_controller->hprq, sci_base_object_get_logger(fw_controller)
126 );
127
128 // Construct the abstract element pool. This pool will store the
129 // references to the framework's remote devices objects.
130 sci_abstract_element_pool_construct(
131 &fw_controller->free_remote_device_pool,
132 fw_controller->remote_device_pool_elements,
133 SCI_MAX_REMOTE_DEVICES
134 );
135
136 // Construct the domain objects.
137 for (index = 0; index < SCI_MAX_DOMAINS; index++)
138 {
139 scif_sas_domain_construct(
140 &fw_controller->domains[index], index, fw_controller
141 );
142 }
143
144 //Initialize SMP PHY MEMORY LIST.
145 sci_fast_list_init(&fw_controller->smp_phy_memory_list);
146
147 for (smp_phy_index = 0;
148 smp_phy_index < SCIF_SAS_SMP_PHY_COUNT;
149 smp_phy_index++)
150 {
151 sci_fast_list_element_init(
152 &fw_controller->smp_phy_array[smp_phy_index],
153 &(fw_controller->smp_phy_array[smp_phy_index].list_element)
154 );
155
156 //insert to owning device's smp phy list.
157 sci_fast_list_insert_tail(
158 (&(fw_controller->smp_phy_memory_list)),
159 (&(fw_controller->smp_phy_array[smp_phy_index].list_element))
160 );
161 }
162
163 scif_sas_controller_set_default_config_parameters(fw_controller);
164
165 fw_controller->internal_request_entries =
166 SCIF_SAS_MAX_INTERNAL_REQUEST_COUNT;
167
168 //@Todo: may need to verify all timers are released. Including domain's
169 //operation timer and all the Internal IO's timer.
170
171 //take care of the lock.
172 scif_cb_lock_disassociate(fw_controller, &fw_controller->hprq.lock);
173 }
174
175 /**
176 * @brief This method implements the actions taken when entering the
177 * INITIALIZING state.
178 *
179 * @param[in] object This parameter specifies the base object for which
180 * the state transition is occurring. This is cast into a
181 * SCIF_SAS_CONTROLLER object in the method implementation.
182 *
183 * @return none
184 */
185 static
186 void scif_sas_controller_initializing_state_enter(
187 SCI_BASE_OBJECT_T * object
188 )
189 {
190 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object;
191
192 SET_STATE_HANDLER(
193 fw_controller,
194 scif_sas_controller_state_handler_table,
195 SCI_BASE_CONTROLLER_STATE_INITIALIZING
196 );
197 }
198
199 /**
200 * @brief This method implements the actions taken when entering the
201 * INITIALIZED state.
202 *
203 * @param[in] object This parameter specifies the base object for which
204 * the state transition is occurring. This is cast into a
205 * SCIF_SAS_CONTROLLER object in the method implementation.
206 *
207 * @return none
208 */
209 static
210 void scif_sas_controller_initialized_state_enter(
211 SCI_BASE_OBJECT_T * object
212 )
213 {
214 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object;
215
216 SET_STATE_HANDLER(
217 fw_controller,
218 scif_sas_controller_state_handler_table,
219 SCI_BASE_CONTROLLER_STATE_INITIALIZED
220 );
221 }
222
223 /**
224 * @brief This method implements the actions taken when entering the
225 * STARTING state.
226 *
227 * @param[in] object This parameter specifies the base object for which
228 * the state transition is occurring. This is cast into a
229 * SCIF_SAS_CONTROLLER object in the method implementation.
230 *
231 * @return none
232 */
233 static
234 void scif_sas_controller_starting_state_enter(
235 SCI_BASE_OBJECT_T * object
236 )
237 {
238 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object;
239
240 SET_STATE_HANDLER(
241 fw_controller,
242 scif_sas_controller_state_handler_table,
243 SCI_BASE_CONTROLLER_STATE_STARTING
244 );
245 }
246
247 /**
248 * @brief This method implements the actions taken when entering the
249 * READY state.
250 *
251 * @param[in] object This parameter specifies the base object for which
252 * the state transition is occurring. This is cast into a
253 * SCIF_SAS_CONTROLLER object in the method implementation.
254 *
255 * @return none
256 */
257 static
258 void scif_sas_controller_ready_state_enter(
259 SCI_BASE_OBJECT_T * object
260 )
261 {
262 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object;
263
264 SET_STATE_HANDLER(
265 fw_controller,
266 scif_sas_controller_state_handler_table,
267 SCI_BASE_CONTROLLER_STATE_READY
268 );
269 }
270
271 /**
272 * @brief This method implements the actions taken when entering the
273 * STOPPING state.
274 *
275 * @param[in] object This parameter specifies the base object for which
276 * the state transition is occurring. This is cast into a
277 * SCIF_SAS_CONTROLLER object in the method implementation.
278 *
279 * @return none
280 */
281 static
282 void scif_sas_controller_stopping_state_enter(
283 SCI_BASE_OBJECT_T * object
284 )
285 {
286 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object;
287
288 SET_STATE_HANDLER(
289 fw_controller,
290 scif_sas_controller_state_handler_table,
291 SCI_BASE_CONTROLLER_STATE_STOPPING
292 );
293 }
294
295 /**
296 * @brief This method implements the actions taken when entering the
297 * STOPPED state.
298 *
299 * @param[in] object This parameter specifies the base object for which
300 * the state transition is occurring. This is cast into a
301 * SCIF_SAS_CONTROLLER object in the method implementation.
302 *
303 * @return none
304 */
305 static
306 void scif_sas_controller_stopped_state_enter(
307 SCI_BASE_OBJECT_T * object
308 )
309 {
310 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object;
311
312 SET_STATE_HANDLER(
313 fw_controller,
314 scif_sas_controller_state_handler_table,
315 SCI_BASE_CONTROLLER_STATE_STOPPED
316 );
317 }
318
319 /**
320 * @brief This method implements the actions taken when entering the
321 * RESETTING state.
322 *
323 * @param[in] object This parameter specifies the base object for which
324 * the state transition is occurring. This is cast into a
325 * SCIF_SAS_CONTROLLER object in the method implementation.
326 *
327 * @return none
328 */
329 static
330 void scif_sas_controller_resetting_state_enter(
331 SCI_BASE_OBJECT_T * object
332 )
333 {
334 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object;
335
336 SET_STATE_HANDLER(
337 fw_controller,
338 scif_sas_controller_state_handler_table,
339 SCI_BASE_CONTROLLER_STATE_RESETTING
340 );
341
342 // Attempt to reset the core controller.
343 fw_controller->operation_status = scic_controller_reset(
344 fw_controller->core_object
345 );
346 if (fw_controller->operation_status == SCI_SUCCESS)
347 {
348 // Reset the framework controller.
349 sci_base_state_machine_change_state(
350 &fw_controller->parent.state_machine,
351 SCI_BASE_CONTROLLER_STATE_RESET
352 );
353 }
354 else
355 {
356 SCIF_LOG_ERROR((
357 sci_base_object_get_logger(fw_controller),
358 SCIF_LOG_OBJECT_CONTROLLER,
359 "Controller: unable to successfully reset controller.\n"
360 ));
361
362 sci_base_state_machine_change_state(
363 &fw_controller->parent.state_machine,
364 SCI_BASE_CONTROLLER_STATE_FAILED
365 );
366 }
367 }
368
369 /**
370 * @brief This method implements the actions taken when entering the
371 * FAILED state.
372 *
373 * @param[in] object This parameter specifies the base object for which
374 * the state transition is occurring. This is cast into a
375 * SCIF_SAS_CONTROLLER object in the method implementation.
376 *
377 * @return none
378 */
379 static
380 void scif_sas_controller_failed_state_enter(
381 SCI_BASE_OBJECT_T * object
382 )
383 {
384 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)object;
385
386 SCIF_LOG_ERROR((
387 sci_base_object_get_logger(fw_controller),
388 SCIF_LOG_OBJECT_CONTROLLER,
389 "Controller: entered FAILED state.\n"
390 ));
391
392 SET_STATE_HANDLER(
393 fw_controller,
394 scif_sas_controller_state_handler_table,
395 SCI_BASE_CONTROLLER_STATE_FAILED
396 );
397
398 if (fw_controller->parent.error != SCI_CONTROLLER_FATAL_MEMORY_ERROR)
399 {
400 //clean timers to avoid timer leak.
401 scif_sas_controller_release_resource(fw_controller);
402
403 //notify user.
404 scif_cb_controller_error(fw_controller, fw_controller->parent.error);
405 }
406 }
407
408 SCI_BASE_STATE_T
409 scif_sas_controller_state_table[SCI_BASE_CONTROLLER_MAX_STATES] =
410 {
411 {
412 SCI_BASE_CONTROLLER_STATE_INITIAL,
413 scif_sas_controller_initial_state_enter,
414 NULL,
415 },
416 {
417 SCI_BASE_CONTROLLER_STATE_RESET,
418 scif_sas_controller_reset_state_enter,
419 NULL,
420 },
421 {
422 SCI_BASE_CONTROLLER_STATE_INITIALIZING,
423 scif_sas_controller_initializing_state_enter,
424 NULL,
425 },
426 {
427 SCI_BASE_CONTROLLER_STATE_INITIALIZED,
428 scif_sas_controller_initialized_state_enter,
429 NULL,
430 },
431 {
432 SCI_BASE_CONTROLLER_STATE_STARTING,
433 scif_sas_controller_starting_state_enter,
434 NULL,
435 },
436 {
437 SCI_BASE_CONTROLLER_STATE_READY,
438 scif_sas_controller_ready_state_enter,
439 NULL,
440 },
441 {
442 SCI_BASE_CONTROLLER_STATE_RESETTING,
443 scif_sas_controller_resetting_state_enter,
444 NULL,
445 },
446 {
447 SCI_BASE_CONTROLLER_STATE_STOPPING,
448 scif_sas_controller_stopping_state_enter,
449 NULL,
450 },
451 {
452 SCI_BASE_CONTROLLER_STATE_STOPPED,
453 scif_sas_controller_stopped_state_enter,
454 NULL,
455 },
456 {
457 SCI_BASE_CONTROLLER_STATE_FAILED,
458 scif_sas_controller_failed_state_enter,
459 NULL,
460 }
461 };
462
Cache object: 4c0e7dc3baf57ebec6bee5c7d2f313ca
|