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 state handler routines for each
62 * of the controller states defined by the SCI_BASE_CONTROLLER state
63 * machine.
64 */
65
66 #include <dev/isci/scil/sci_util.h>
67 #include <dev/isci/scil/scic_controller.h>
68 #include <dev/isci/scil/scic_port.h>
69 #include <dev/isci/scil/scic_remote_device.h>
70 #include <dev/isci/scil/scic_io_request.h>
71
72 #include <dev/isci/scil/scif_sas_controller.h>
73 #include <dev/isci/scil/scif_sas_remote_device.h>
74 #include <dev/isci/scil/scif_sas_logger.h>
75 #include <dev/isci/scil/scif_sas_smp_remote_device.h>
76
77 //******************************************************************************
78 //* P R I V A T E M E T H O D S
79 //******************************************************************************
80
81 /**
82 * @brief This method simply executes the reset operation by entering
83 * the reset state and allowing the state to perform it's work.
84 *
85 * @param[in] fw_controller This parameter specifies the SAS framework
86 * controller for execute the reset.
87 *
88 * @return Indicate the status of the reset operation. Was it successful?
89 * @retval SCI_SUCCESS This value is returned if it was successfully reset.
90 */
91 static
92 SCI_STATUS scif_sas_controller_execute_reset(
93 SCIF_SAS_CONTROLLER_T * fw_controller
94 )
95 {
96 SCI_STATUS status;
97
98 SCIF_LOG_TRACE((
99 sci_base_object_get_logger(fw_controller),
100 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_CONTROLLER_RESET,
101 "scif_sas_controller_execute_reset(0x%x) enter\n",
102 fw_controller
103 ));
104
105 //clean the timer to avoid timer leak.
106 scif_sas_controller_release_resource(fw_controller);
107
108 sci_base_state_machine_change_state(
109 &fw_controller->parent.state_machine,
110 SCI_BASE_CONTROLLER_STATE_RESETTING
111 );
112
113 // Retrieve the status for the operations performed during the entrance
114 // to the resetting state were executing successfully.
115 status = fw_controller->operation_status;
116 fw_controller->operation_status = SCI_SUCCESS;
117
118 return status;
119 }
120
121 /**
122 * @brief This method checks that the memory descriptor list is valid
123 * and hasn't been corrupted in some way by the user.
124 *
125 * @param[in] fw_controller This parameter specifies the framework
126 * controller object for which to validation the MDL.
127 *
128 * @return This method returns a value indicating if the operation succeeded.
129 * @retval SCI_SUCCESS This value indicates that MDL is valid.
130 * @retval SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD This value indicates
131 * that some portion of the memory descriptor list is invalid.
132 */
133 static
134 SCI_STATUS scif_sas_controller_validate_mdl(
135 SCIF_SAS_CONTROLLER_T * fw_controller
136 )
137 {
138 BOOL is_mde_list_valid;
139
140 // Currently there is only a single MDE in the list.
141 is_mde_list_valid = sci_base_mde_is_valid(
142 &fw_controller->mdes[SCIF_SAS_MDE_INTERNAL_IO],
143 4,
144 fw_controller->internal_request_entries *
145 scif_sas_internal_request_get_object_size(),
146 SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS
147 );
148
149 if (is_mde_list_valid == FALSE)
150 return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD;
151
152 return SCI_SUCCESS;
153 }
154
155
156 /**
157 * @brief This method stops all the domains associated to this
158 * controller.
159 *
160 * @param[in] fw_controller This parameter specifies the framework
161 * controller object for whose remote devices are to be stopped.
162 *
163 * @return This method returns a value indicating if the operation succeeded.
164 * @retval SCI_SUCCESS This value indicates that all the devices are stopped.
165 * @retval SCI_FAILURE This value indicates certain failure during the process
166 * of stopping remote devices.
167 */
168 static
169 SCI_STATUS scif_sas_controller_stop_domains(
170 SCIF_SAS_CONTROLLER_T * fw_controller
171 )
172 {
173 U8 index;
174 SCI_STATUS status = SCI_SUCCESS;
175 SCIF_SAS_DOMAIN_T * fw_domain;
176
177 SCIF_LOG_TRACE((
178 sci_base_object_get_logger(fw_controller),
179 SCIF_LOG_OBJECT_CONTROLLER,
180 "scif_sas_controller_stop_domains(0x%x) enter\n",
181 fw_controller
182 ));
183
184 for (index = 0; index < SCI_MAX_DOMAINS && status == SCI_SUCCESS; index++)
185 {
186 fw_domain = &fw_controller->domains[index];
187
188 //Change this domain to STOPPING state. All the remote devices will be
189 //stopped subsquentially.
190 if (fw_domain->parent.state_machine.current_state_id ==
191 SCI_BASE_DOMAIN_STATE_READY
192 || fw_domain->parent.state_machine.current_state_id ==
193 SCI_BASE_DOMAIN_STATE_DISCOVERING)
194 {
195 sci_base_state_machine_change_state(
196 &fw_domain->parent.state_machine, SCI_BASE_DOMAIN_STATE_STOPPING
197 );
198 }
199 }
200
201 return status;
202 }
203
204
205 /**
206 * @brief This method continue to stop the controller after clear affiliation
207 * is done.
208 *
209 * @param[in] fw_controller This parameter specifies the framework
210 * controller object to be stopped.
211 *
212 * @return This method returns a value indicating if the operation succeeded.
213 * @retval SCI_SUCCESS This value indicates the controller_stop succeeds.
214 * @retval SCI_FAILURE This value indicates certain failure during the process
215 * of stopping controller.
216 */
217 SCI_STATUS scif_sas_controller_continue_to_stop(
218 SCIF_SAS_CONTROLLER_T * fw_controller
219 )
220 {
221 SCI_STATUS status;
222
223 SCIF_LOG_TRACE((
224 sci_base_object_get_logger(fw_controller),
225 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_SHUTDOWN,
226 "scif_sas_controller_continue_to_stop (0x%x).\n",
227 fw_controller
228 ));
229
230 //stop all the domains and their remote devices.
231 status = scif_sas_controller_stop_domains(fw_controller);
232
233 if (status == SCI_SUCCESS)
234 {
235 // Attempt to stop the core controller.
236 status = scic_controller_stop(fw_controller->core_object, 0);
237
238 if (status != SCI_SUCCESS)
239 {
240 SCIF_LOG_ERROR((
241 sci_base_object_get_logger(fw_controller),
242 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_SHUTDOWN,
243 "Controller:0x%x Status:0x%x unable to stop controller.\n",
244 fw_controller, status
245 ));
246
247 sci_base_state_machine_change_state(
248 &fw_controller->parent.state_machine,
249 SCI_BASE_CONTROLLER_STATE_FAILED
250 );
251 }
252 }
253 else
254 {
255 SCIF_LOG_ERROR((
256 sci_base_object_get_logger(fw_controller),
257 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_SHUTDOWN,
258 "Controller:0x%x Status:0x%x unable to stop domains.\n",
259 fw_controller, status
260 ));
261
262 sci_base_state_machine_change_state(
263 &fw_controller->parent.state_machine,
264 SCI_BASE_CONTROLLER_STATE_FAILED
265 );
266 }
267
268 return status;
269 }
270
271
272 //******************************************************************************
273 //* R E S E T H A N D L E R S
274 //******************************************************************************
275
276 /**
277 * @brief This method provides RESET state specific handling for
278 * when a user attempts to initialize a controller. This is a legal
279 * state in which to attempt an initialize call.
280 *
281 * @param[in] controller This parameter specifies the controller object
282 * on which the user is attempting to perform an initialize
283 * operation.
284 *
285 * @return This method returns an indication of whether the initialize
286 * operation succeeded.
287 * @retval SCI_SUCCESS This value when the initialization completes
288 * successfully.
289 */
290 static
291 SCI_STATUS scif_sas_controller_reset_initialize_handler(
292 SCI_BASE_CONTROLLER_T * controller
293 )
294 {
295 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)controller;
296 SCI_STATUS status;
297 U32 index;
298
299 SCIF_LOG_TRACE((
300 sci_base_object_get_logger(fw_controller),
301 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION,
302 "scif_sas_controller_reset_initialize_handler(0x%x) enter\n",
303 controller
304 ));
305
306 sci_base_state_machine_change_state(
307 &fw_controller->parent.state_machine,
308 SCI_BASE_CONTROLLER_STATE_INITIALIZING
309 );
310
311 scif_sas_controller_build_mdl(fw_controller);
312
313 // Perform any domain object initialization that is necessary.
314 for (index = 0; index < SCI_MAX_DOMAINS; index++)
315 scif_sas_domain_initialize(&fw_controller->domains[index]);
316
317 scif_cb_lock_associate(fw_controller, &fw_controller->hprq.lock);
318
319 // Attempt to initialize the core controller.
320 status = scic_controller_initialize(fw_controller->core_object);
321 if (status == SCI_SUCCESS)
322 {
323 sci_base_state_machine_change_state(
324 &fw_controller->parent.state_machine,
325 SCI_BASE_CONTROLLER_STATE_INITIALIZED
326 );
327 }
328
329 if (status != SCI_SUCCESS)
330 {
331 // Initialization failed, Release resources and do not change state
332 scif_sas_controller_release_resource(fw_controller);
333
334 SCIF_LOG_ERROR((
335 sci_base_object_get_logger(fw_controller),
336 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION,
337 "Controller:0x%x Status:0x%x unable to successfully initialize.\n",
338 fw_controller, status
339 ));
340 }
341
342 return status;
343 }
344
345 //******************************************************************************
346 //* I N I T I A L I Z E D H A N D L E R S
347 //******************************************************************************
348
349 /**
350 * @brief This method provides INITIALIZED state specific handling for
351 * when a user attempts to start a controller.
352 *
353 * @param[in] controller This parameter specifies the controller object
354 * on which the user is attempting to perform a start
355 * operation.
356 * @param[in] timeout This parameter specifies the timeout value (in
357 * milliseconds) to be utilized for this operation.
358 *
359 * @return This method returns an indication of whether the start operation
360 * succeeded.
361 * @retval SCI_SUCCESS This value is returned when the start operation
362 * begins successfully.
363 */
364 static
365 SCI_STATUS scif_sas_controller_initialized_start_handler(
366 SCI_BASE_CONTROLLER_T * controller,
367 U32 timeout
368 )
369 {
370 SCI_STATUS status = SCI_SUCCESS;
371 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)controller;
372 U16 index = 0;
373
374 SCI_PHYSICAL_MEMORY_DESCRIPTOR_T internal_reqeust_mde =
375 fw_controller->mdes[SCIF_SAS_MDE_INTERNAL_IO];
376
377 void * internal_request_virtual_address = internal_reqeust_mde.virtual_address;
378 POINTER_UINT address = (POINTER_UINT)internal_request_virtual_address;
379
380 SCIF_LOG_TRACE((
381 sci_base_object_get_logger(fw_controller),
382 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION,
383 "scif_sas_controller_initialized_start_handler(0x%x, 0x%x) enter\n",
384 controller, timeout
385 ));
386
387 sci_base_state_machine_change_state(
388 &fw_controller->parent.state_machine,
389 SCI_BASE_CONTROLLER_STATE_STARTING
390 );
391
392 status = scif_sas_controller_validate_mdl(fw_controller);
393
394 // initialization work for internal request path. It must be done before
395 // starting domain.
396 if (status == SCI_SUCCESS)
397 {
398 // fill in the sci_pool for internal requests.
399 sci_pool_initialize(fw_controller->internal_request_memory_pool);
400
401 for (index = 0; index < fw_controller->internal_request_entries; index++)
402 {
403 sci_pool_put(fw_controller->internal_request_memory_pool, address);
404
405 address += scif_sas_internal_request_get_object_size();
406 }
407
408 // Using DPC for starting internal IOs, if yes, we need to intialize
409 // DPC here.
410 scif_cb_start_internal_io_task_create(fw_controller);
411 }
412
413 if (status == SCI_SUCCESS)
414 {
415 // Kick-start the domain state machines and, by association, the
416 // core port's.
417
418 // This will ensure we get valid port objects supplied with link up
419 // messages.
420 for (index = 0;
421 (index < SCI_MAX_DOMAINS) && (status == SCI_SUCCESS);
422 index++)
423 {
424 sci_base_state_machine_change_state(
425 &fw_controller->domains[index].parent.state_machine,
426 SCI_BASE_DOMAIN_STATE_STARTING
427 );
428 status = fw_controller->domains[index].operation.status;
429 }
430 }
431
432 // Validate that all the domain state machines began successfully.
433 if (status != SCI_SUCCESS)
434 {
435 SCIF_LOG_ERROR((
436 sci_base_object_get_logger(fw_controller),
437 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION,
438 "Controller:0x%x Domain:0x%x Status:0x%x unable to start\n",
439 fw_controller, index, status
440 ));
441
442 return status;
443 }
444
445 // Attempt to start the core controller.
446 status = scic_controller_start(fw_controller->core_object, timeout);
447 if (status != SCI_SUCCESS)
448 {
449 SCIF_LOG_ERROR((
450 sci_base_object_get_logger(fw_controller),
451 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION,
452 "Controller:0x%x Status:0x%x unable to start controller.\n",
453 fw_controller, status
454 ));
455
456 sci_base_state_machine_change_state(
457 &fw_controller->parent.state_machine,
458 SCI_BASE_CONTROLLER_STATE_FAILED
459 );
460 }
461
462 return status;
463 }
464
465 //******************************************************************************
466 //* R E A D Y H A N D L E R S
467 //******************************************************************************
468
469 /**
470 * @brief This method provides READY state specific handling for
471 * when a user attempts to stop a controller.
472 *
473 * @param[in] controller This parameter specifies the controller object
474 * on which the user is attempting to perform a stop
475 * operation.
476 * @param[in] timeout This parameter specifies the timeout value (in
477 * milliseconds) to be utilized for this operation.
478 *
479 * @return This method returns an indication of whether the stop operation
480 * succeeded.
481 * @retval SCI_SUCCESS This value is returned when the stop operation
482 * begins successfully.
483 */
484 static
485 SCI_STATUS scif_sas_controller_ready_stop_handler(
486 SCI_BASE_CONTROLLER_T * controller,
487 U32 timeout
488 )
489 {
490 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)controller;
491
492 SCIF_LOG_TRACE((
493 sci_base_object_get_logger(fw_controller),
494 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_INITIALIZATION,
495 "scif_sas_controller_ready_stop_handler(0x%x, 0x%x) enter\n",
496 controller, timeout
497 ));
498
499 sci_base_state_machine_change_state(
500 &fw_controller->parent.state_machine,
501 SCI_BASE_CONTROLLER_STATE_STOPPING
502 );
503
504 if (fw_controller->user_parameters.sas.clear_affiliation_during_controller_stop)
505 {
506 fw_controller->current_domain_to_clear_affiliation = 0;
507
508 //clear affiliation first. After the last domain finishes clearing
509 //affiliation, it will call back to controller to continue to stop.
510 scif_sas_controller_clear_affiliation(fw_controller);
511 }
512 else
513 scif_sas_controller_continue_to_stop(fw_controller);
514
515 //Must return SUCCESS at this point.
516 return SCI_SUCCESS;
517 }
518
519 /**
520 * @brief This method provides READY state specific handling for
521 * when a user attempts to reset a controller.
522 *
523 * @param[in] controller This parameter specifies the controller object
524 * on which the user is attempting to perform a reset
525 * operation.
526 *
527 * @return This method returns an indication of whether the reset operation
528 * succeeded.
529 * @retval SCI_SUCCESS This value is returned when the reset operation
530 * completes successfully.
531 */
532 static
533 SCI_STATUS scif_sas_controller_ready_reset_handler(
534 SCI_BASE_CONTROLLER_T * controller
535 )
536 {
537 return scif_sas_controller_execute_reset((SCIF_SAS_CONTROLLER_T*)controller);
538 }
539
540 /**
541 * @brief This method provides READY state specific handling for
542 * when a user attempts to start an IO request.
543 *
544 * @param[in] controller This parameter specifies the controller object
545 * on which the user is attempting to perform a start IO
546 * operation.
547 * @param[in] remote_device This parameter specifies the remote deivce
548 * object on which the user is attempting to perform a start IO
549 * operation.
550 * @param[in] io_request This parameter specifies the IO request to be
551 * started.
552 * @param[in] io_tag This parameter specifies the optional allocated
553 * IO tag. Please reference scif_controller_start_io() for
554 * more information.
555 *
556 * @return This method returns an indication of whether the start IO
557 * operation succeeded.
558 * @retval SCI_SUCCESS This value is returned when the start IO operation
559 * begins successfully.
560 */
561 static
562 SCI_STATUS scif_sas_controller_ready_start_io_handler(
563 SCI_BASE_CONTROLLER_T * controller,
564 SCI_BASE_REMOTE_DEVICE_T * remote_device,
565 SCI_BASE_REQUEST_T * io_request,
566 U16 io_tag
567 )
568 {
569 SCI_STATUS status;
570 SCIF_SAS_IO_REQUEST_T *fw_io = (SCIF_SAS_IO_REQUEST_T*)io_request;
571 SCIF_SAS_CONTROLLER_T *fw_controller = (SCIF_SAS_CONTROLLER_T*)controller;
572 SCIF_SAS_REMOTE_DEVICE_T *fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
573 remote_device;
574
575 SCIF_LOG_TRACE((
576 sci_base_object_get_logger(fw_controller),
577 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST,
578 "scif_sas_controller_ready_start_io_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
579 controller, remote_device, io_request, io_tag
580 ));
581
582 status = fw_device->domain->state_handlers->start_io_handler(
583 &fw_device->domain->parent, remote_device, io_request
584 );
585
586 // Check to see that the other objects in the framework allowed
587 // this IO to be started.
588 if (status == SCI_SUCCESS)
589 {
590 // Ask the core to start processing for this IO request.
591 status = (SCI_STATUS)scic_controller_start_io(
592 fw_controller->core_object,
593 fw_device->core_object,
594 fw_io->parent.core_object,
595 io_tag
596 );
597
598 if (status == SCI_SUCCESS)
599 {
600 // We were able to start the core request. As a result,
601 // commit to starting the request for the framework by changing
602 // the state of the IO request.
603 sci_base_state_machine_change_state(
604 &io_request->state_machine, SCI_BASE_REQUEST_STATE_STARTED
605 );
606 }
607 else
608 {
609 // We were unable to start the core IO request. As a result,
610 // back out the start operation for the framework. It's easier to
611 // back out the framework start operation then to backout the core
612 // start IO operation.
613 fw_device->domain->state_handlers->complete_io_handler(
614 &fw_device->domain->parent, remote_device, io_request
615 );
616
617 // Invoke the IO completion handler. For most IOs, this does nothing
618 // since we are still in the constructed state. For NCQ, this will
619 // the return of the NCQ tag back to the remote device free pool.
620 fw_io->parent.state_handlers->complete_handler(io_request);
621
622 SCIF_LOG_WARNING((
623 sci_base_object_get_logger(fw_controller),
624 SCIF_LOG_OBJECT_CONTROLLER,
625 "Controller:0x%x IORequest:0x%x Status:0x%x core IO start failed\n",
626 fw_controller, fw_io, status
627 ));
628 }
629 }
630 else
631 {
632 SCIF_LOG_WARNING((
633 sci_base_object_get_logger(fw_controller),
634 SCIF_LOG_OBJECT_CONTROLLER,
635 "Controller:0x%x IORequest:0x%x Status:0x%x IO start failed\n",
636 fw_controller, fw_io, status
637 ));
638 }
639
640 return status;
641 }
642
643 /**
644 * @brief This method provides READY state specific handling for
645 * when a user attempts to complete an IO request.
646 *
647 * @param[in] controller This parameter specifies the controller object
648 * on which the user is attempting to perform a complete IO
649 * operation.
650 * @param[in] remote_device This parameter specifies the remote deivce
651 * object on which the user is attempting to perform a start IO
652 * operation.
653 * @param[in] io_request This parameter specifies the IO request to be
654 * started.
655 *
656 * @return This method returns an indication of whether the complete IO
657 * operation succeeded.
658 * @retval SCI_SUCCESS This value is returned when the complete IO operation
659 * begins successfully.
660 */
661 static
662 SCI_STATUS scif_sas_controller_ready_complete_io_handler(
663 SCI_BASE_CONTROLLER_T * controller,
664 SCI_BASE_REMOTE_DEVICE_T * remote_device,
665 SCI_BASE_REQUEST_T * io_request
666 )
667 {
668 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*)
669 controller;
670 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
671 remote_device;
672 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*)
673 io_request;
674 SCI_STATUS status;
675 SCI_STATUS core_status;
676
677 SCIF_LOG_TRACE((
678 sci_base_object_get_logger(fw_controller),
679 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST,
680 "scif_sas_controller_ready_complete_io_handler(0x%x, 0x%x, 0x%x) enter\n",
681 controller, remote_device, io_request
682 ));
683
684 fw_io->parent.state_handlers->destruct_handler(&fw_io->parent.parent);
685 status = fw_device->domain->state_handlers->complete_io_handler(
686 &fw_device->domain->parent, remote_device, io_request
687 );
688
689 // Ask the core to finish processing for this IO request.
690 core_status = scic_controller_complete_io(
691 fw_controller->core_object,
692 fw_device->core_object,
693 fw_io->parent.core_object
694 );
695
696 if (status == SCI_SUCCESS)
697 status = core_status;
698
699 if (status != SCI_SUCCESS)
700 {
701 SCIF_LOG_WARNING((
702 sci_base_object_get_logger(fw_controller),
703 SCIF_LOG_OBJECT_CONTROLLER,
704 "Controller:0x%x IORequest:0x%x Status:0x%x CoreStatus:0x%x "
705 "failure to complete IO\n",
706 fw_controller, fw_io, status, core_status
707 ));
708 }
709
710 return status;
711 }
712
713
714 /**
715 * @brief This method provides READY state specific handling for
716 * when a user attempts to complete a high priority IO request.
717 *
718 * @param[in] controller This parameter specifies the controller object
719 * on which the user is attempting to perform a complete IO
720 * operation.
721 * @param[in] remote_device This parameter specifies the remote deivce
722 * object on which the user is attempting to perform a start IO
723 * operation.
724 * @param[in] io_request This parameter specifies the IO request to be
725 * started.
726 *
727 * @return This method returns an indication of whether the complete IO
728 * operation succeeded.
729 * @retval SCI_SUCCESS This value is returned when the complete IO operation
730 * begins successfully.
731 */
732 static
733 SCI_STATUS scif_sas_controller_ready_complete_high_priority_io_handler(
734 SCI_BASE_CONTROLLER_T * controller,
735 SCI_BASE_REMOTE_DEVICE_T * remote_device,
736 SCI_BASE_REQUEST_T * io_request
737 )
738 {
739 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*)
740 controller;
741 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
742 remote_device;
743 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T*)
744 io_request;
745 SCI_IO_STATUS core_completion_status =
746 scic_request_get_sci_status(fw_io->parent.core_object);
747
748 U8 response_data[SCIF_SAS_RESPONSE_DATA_LENGTH];
749
750 SCI_STATUS status;
751 SCI_STATUS core_status;
752
753 SCIF_LOG_TRACE((
754 sci_base_object_get_logger(fw_controller),
755 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST,
756 "scif_sas_controller_ready_complete_high_priority_io_handler(0x%x, 0x%x, 0x%x) enter\n",
757 controller, remote_device, io_request
758 ));
759
760 // In high priority path, we ask the core to finish IO request before framework.
761
762 // retrieve and save io response from core now.
763 memcpy(response_data,
764 scic_io_request_get_response_iu_address(fw_io->parent.core_object),
765 SCIF_SAS_RESPONSE_DATA_LENGTH
766 );
767
768 core_status = scic_controller_complete_io(
769 fw_controller->core_object,
770 fw_device->core_object,
771 fw_io->parent.core_object
772 );
773
774 fw_io->parent.state_handlers->destruct_handler(&fw_io->parent.parent);
775 status = fw_device->domain->state_handlers->complete_high_priority_io_handler(
776 &fw_device->domain->parent,
777 remote_device,
778 io_request,
779 (void *)response_data,
780 core_completion_status
781 );
782
783 if (status == SCI_SUCCESS)
784 status = core_status;
785
786 if (status == SCI_SUCCESS)
787 {
788 //issue DPC to start next internal io in high prioriy queue.
789 if( !sci_pool_empty(fw_controller->hprq.pool) )
790 scif_cb_start_internal_io_task_schedule(
791 fw_controller,
792 scif_sas_controller_start_high_priority_io,
793 fw_controller
794 );
795 }
796 else
797 {
798 SCIF_LOG_WARNING((
799 sci_base_object_get_logger(fw_controller),
800 SCIF_LOG_OBJECT_CONTROLLER,
801 "Controller:0x%x IORequest:0x%x Status:0x%x CoreStatus:0x%x "
802 "failure to complete IO\n",
803 fw_controller, fw_io, status, core_status
804 ));
805 }
806
807 return status;
808 }
809
810 /**
811 * @brief This method provides READY state specific handling for
812 * when a user attempts to continue an IO request.
813 *
814 * @param[in] controller This parameter specifies the controller object
815 * on which the user is attempting to perform a continue IO
816 * operation.
817 * @param[in] remote_device This parameter specifies the remote deivce
818 * object on which the user is attempting to perform a start IO
819 * operation.
820 * @param[in] io_request This parameter specifies the IO request to be
821 * started.
822 *
823 * @return This method returns an indication of whether the continue IO
824 * operation succeeded.
825 * @retval SCI_SUCCESS This value is returned when the continue IO operation
826 * begins successfully.
827 */
828 static
829 SCI_STATUS scif_sas_controller_ready_continue_io_handler(
830 SCI_BASE_CONTROLLER_T * controller,
831 SCI_BASE_REMOTE_DEVICE_T * remote_device,
832 SCI_BASE_REQUEST_T * io_request
833 )
834 {
835 SCIF_LOG_TRACE((
836 sci_base_object_get_logger(controller),
837 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST,
838 "scif_sas_controller_ready_continue_io_handler(0x%x, 0x%x, 0x%x) enter\n",
839 controller, remote_device, io_request
840 ));
841
842 /// @todo Function unimplemented. fix return code handling.
843 return SCI_FAILURE;
844 }
845
846 /**
847 * @brief This method provides READY state specific handling for
848 * when a user attempts to start a task request.
849 *
850 * @param[in] controller This parameter specifies the controller object
851 * on which the user is attempting to perform a start task
852 * operation.
853 * @param[in] remote_device This parameter specifies the remote deivce
854 * object on which the user is attempting to perform a start
855 * task operation.
856 * @param[in] task_request This parameter specifies the task management
857 * request to be started.
858 * @param[in] io_tag This parameter specifies the optional allocated
859 * IO tag. Please reference scif_controller_start_task() for
860 * more information.
861 *
862 * @return This method returns an indication of whether the start task
863 * operation succeeded.
864 * @retval SCI_SUCCESS This value is returned when the start task operation
865 * begins successfully.
866 */
867 static
868 SCI_STATUS scif_sas_controller_ready_start_task_handler(
869 SCI_BASE_CONTROLLER_T * controller,
870 SCI_BASE_REMOTE_DEVICE_T * remote_device,
871 SCI_BASE_REQUEST_T * task_request,
872 U16 io_tag
873 )
874 {
875 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T*)
876 controller;
877 SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
878 remote_device;
879 SCIF_SAS_TASK_REQUEST_T * fw_task = (SCIF_SAS_TASK_REQUEST_T*)task_request;
880 SCI_STATUS status;
881
882 SCIF_LOG_TRACE((
883 sci_base_object_get_logger(fw_controller),
884 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
885 "scif_sas_controller_ready_start_task_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
886 controller, remote_device, task_request, io_tag
887 ));
888
889 status = fw_device->domain->state_handlers->start_task_handler(
890 &fw_device->domain->parent, remote_device, task_request
891 );
892
893 if (status == SCI_SUCCESS)
894 {
895 if (scif_sas_task_request_get_function(fw_task)
896 == SCI_SAS_HARD_RESET)
897 {
898 // Go off to special target reset path. Don't start task to core.
899 scif_sas_remote_device_target_reset(
900 fw_device,
901 (SCIF_SAS_REQUEST_T *)fw_task
902 );
903
904 return SCI_SUCCESS;
905 }
906
907 // Ask the core to start processing for this task request.
908 status = (SCI_STATUS)scic_controller_start_task(
909 fw_controller->core_object,
910 fw_device->core_object,
911 fw_task->parent.core_object,
912 io_tag
913 );
914
915 if (status == SCI_SUCCESS)
916 {
917 // We were able to start the core request. As a result,
918 // commit to starting the request for the framework by changing
919 // the state of the task request.
920 fw_task->parent.state_handlers->start_handler(&fw_task->parent.parent);
921 }
922 else
923 {
924 // We were unable to start the core task request. As a result,
925 // back out the start operation for the framework. It's easier to
926 // back out the framework start operation then to backout the core
927 // start task operation.
928 fw_device->domain->state_handlers->complete_task_handler(
929 &fw_device->domain->parent, remote_device, task_request
930 );
931
932 if (status == SCI_SUCCESS)
933 {
934 SCIF_LOG_WARNING((
935 sci_base_object_get_logger(fw_controller),
936 SCIF_LOG_OBJECT_CONTROLLER,
937 "Controller:0x%x TaskRequest:0x%x Status:0x%x core start failed\n",
938 fw_controller, fw_task, status
939 ));
940 }
941 }
942 }
943 else
944 {
945 SCIF_LOG_WARNING((
946 sci_base_object_get_logger(fw_controller),
947 SCIF_LOG_OBJECT_CONTROLLER,
948 "Controller:0x%x TaskRequest:0x%x Status:0x%x Task start failed\n",
949 fw_controller, fw_task, status
950 ));
951 }
952
953 return status;
954 }
955
956 /**
957 * @brief This method provides READY state specific handling for
958 * when a user attempts to complete a task request.
959 *
960 * @param[in] controller This parameter specifies the controller object
961 * on which the user is attempting to perform a complete task
962 * operation.
963 * @param[in] remote_device This parameter specifies the remote deivce
964 * object on which the user is attempting to perform a start
965 * task operation.
966 * @param[in] task_request This parameter specifies the task management
967 * request to be started.
968 *
969 * @return This method returns an indication of whether the complete task
970 * operation succeeded.
971 * @retval SCI_SUCCESS This value is returned when the complete task operation
972 * begins successfully.
973 */
974 static
975 SCI_STATUS scif_sas_controller_ready_complete_task_handler(
976 SCI_BASE_CONTROLLER_T * controller,
977 SCI_BASE_REMOTE_DEVICE_T * remote_device,
978 SCI_BASE_REQUEST_T * task_request
979 )
980 {
981 SCIF_SAS_CONTROLLER_T *fw_controller = (SCIF_SAS_CONTROLLER_T*)controller;
982 SCIF_SAS_REMOTE_DEVICE_T *fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)remote_device;
983 SCIF_SAS_TASK_REQUEST_T *fw_task = (SCIF_SAS_TASK_REQUEST_T*)task_request;
984 SCI_STATUS status;
985 SCI_STATUS core_status;
986
987 SCIF_LOG_TRACE((
988 sci_base_object_get_logger(fw_controller),
989 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
990 "scif_sas_controller_ready_complete_task_handler(0x%x, 0x%x, 0x%x) enter\n",
991 controller, remote_device, task_request
992 ));
993
994 status = fw_device->domain->state_handlers->complete_task_handler(
995 &fw_device->domain->parent, remote_device, task_request
996 );
997
998 if (scif_sas_task_request_get_function(fw_task)
999 == SCI_SAS_HARD_RESET)
1000 {
1001 //No more things to do in the core, since this task is for Target Reset.
1002 return status;
1003 }
1004
1005 fw_task->parent.state_handlers->destruct_handler(&fw_task->parent.parent);
1006
1007 // Ask the core to finish processing for this task request.
1008 core_status = scic_controller_complete_task(
1009 fw_controller->core_object,
1010 fw_device->core_object,
1011 fw_task->parent.core_object
1012 );
1013
1014 if (status == SCI_SUCCESS)
1015 status = core_status;
1016
1017 if (status != SCI_SUCCESS)
1018 {
1019 SCIF_LOG_WARNING((
1020 sci_base_object_get_logger(fw_controller),
1021 SCIF_LOG_OBJECT_CONTROLLER,
1022 "Controller:0x%x TaskRequest:0x%x Status:0x%x CoreStatus:0x%x "
1023 "failed to complete\n",
1024 fw_controller, fw_task, status, core_status
1025 ));
1026 }
1027
1028 return status;
1029 }
1030
1031
1032
1033 /**
1034 * @brief This method provides common handling for several states
1035 * when a user attempts to start an internal request.
1036 *
1037 * @param[in] controller This parameter specifies the controller object
1038 * on which the user is attempting to perform a start IO
1039 * operation.
1040 * @param[in] remote_device This parameter specifies the remote deivce
1041 * object on which the user is attempting to perform a start IO
1042 * operation.
1043 * @param[in] io_request This parameter specifies the IO request to be
1044 * started.
1045 * @param[in] io_tag This parameter specifies the optional allocated
1046 * IO tag. Please reference scif_controller_start_io() for
1047 * more information.
1048 *
1049 * @return This method returns an indication of whether the start IO
1050 * operation succeeded.
1051 * @retval SCI_SUCCESS This value is returned when the start IO operation
1052 * begins successfully.
1053 */
1054 static
1055 SCI_STATUS scif_sas_controller_common_start_high_priority_io_handler(
1056 SCI_BASE_CONTROLLER_T * controller,
1057 SCI_BASE_REMOTE_DEVICE_T * remote_device,
1058 SCI_BASE_REQUEST_T * io_request,
1059 U16 io_tag
1060 )
1061 {
1062 SCI_STATUS status;
1063 SCIF_SAS_IO_REQUEST_T *fw_io = (SCIF_SAS_IO_REQUEST_T*)io_request;
1064 SCIF_SAS_CONTROLLER_T *fw_controller = (SCIF_SAS_CONTROLLER_T*)controller;
1065 SCIF_SAS_REMOTE_DEVICE_T *fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
1066 remote_device;
1067
1068 status = fw_device->domain->state_handlers->start_high_priority_io_handler(
1069 &fw_device->domain->parent, remote_device, io_request
1070 );
1071
1072 // Check to see that the other objects in the framework allowed
1073 // this IO to be started.
1074 if (status == SCI_SUCCESS)
1075 {
1076 // Ask the core to start processing for this IO request.
1077 status = (SCI_STATUS)scic_controller_start_io(
1078 fw_controller->core_object,
1079 fw_device->core_object,
1080 fw_io->parent.core_object,
1081 io_tag
1082 );
1083
1084 if (status == SCI_SUCCESS)
1085 {
1086 // We were able to start the core request. As a result,
1087 // commit to starting the request for the framework by changing
1088 // the state of the IO request.
1089 sci_base_state_machine_change_state(
1090 &io_request->state_machine, SCI_BASE_REQUEST_STATE_STARTED
1091 );
1092 }
1093 else
1094 {
1095 // We were unable to start the core IO request. As a result,
1096 // back out the start operation for the framework. It's easier to
1097 // back out the framework start operation then to backout the core
1098 // start IO operation.
1099 fw_device->domain->state_handlers->complete_io_handler(
1100 &fw_device->domain->parent, remote_device, io_request
1101 );
1102
1103 // Invoke the IO completion handler. For most IOs, this does nothing
1104 // since we are still in the constructed state. For NCQ, this will
1105 // the return of the NCQ tag back to the remote device free pool.
1106 fw_io->parent.state_handlers->complete_handler(io_request);
1107
1108 SCIF_LOG_WARNING((
1109 sci_base_object_get_logger(fw_controller),
1110 SCIF_LOG_OBJECT_CONTROLLER,
1111 "Controller:0x%x IORequest:0x%x Status:0x%x core IO start failed\n",
1112 fw_controller, fw_io, status
1113 ));
1114 }
1115 }
1116 else
1117 {
1118 SCIF_LOG_WARNING((
1119 sci_base_object_get_logger(fw_controller),
1120 SCIF_LOG_OBJECT_CONTROLLER,
1121 "Controller:0x%x IORequest:0x%x Status:0x%x IO start failed\n",
1122 fw_controller, fw_io, status
1123 ));
1124
1125 // Invoke the IO completion handler. For most IOs, this does nothing
1126 // since we are still in the constructed state. For NCQ, this will
1127 // the return of the NCQ tag back to the remote device free pool.
1128 fw_io->parent.state_handlers->complete_handler(io_request);
1129
1130 }
1131
1132 if (fw_io->parent.is_internal && status != SCI_SUCCESS )
1133 {
1134 SCIC_TRANSPORT_PROTOCOL protocol =
1135 scic_io_request_get_protocol(fw_io->parent.core_object);
1136
1137 U8 retry_count = fw_io->retry_count;
1138
1139 scif_sas_internal_io_request_destruct(
1140 fw_device->domain->controller,
1141 (SCIF_SAS_INTERNAL_IO_REQUEST_T *)fw_io
1142 );
1143
1144 if ( protocol == SCIC_SMP_PROTOCOL )
1145 {
1146 if (fw_device->protocol_device.smp_device.smp_activity_timer != NULL)
1147 {
1148 //destroy the smp_activity_timer
1149 scif_cb_timer_destroy (
1150 fw_controller,
1151 fw_device->protocol_device.smp_device.smp_activity_timer
1152 );
1153
1154 fw_device->protocol_device.smp_device.smp_activity_timer = NULL;
1155 }
1156
1157 //we should retry for finite times
1158 if ( retry_count < SCIF_SAS_IO_RETRY_LIMIT)
1159 {
1160 //An internal smp request failed being started, most likely due to remote device
1161 //is not in ready state, for example, UPDATING_PORT_WIDTH state. In this case,
1162 //we should retry the IO.
1163 scif_sas_smp_remote_device_retry_internal_io(
1164 (SCIF_SAS_REMOTE_DEVICE_T *)remote_device,
1165 retry_count,
1166 SMP_REQUEST_RETRY_WAIT_DURATION
1167 );
1168 }
1169 }
1170 }
1171
1172 return status;
1173 }
1174
1175
1176 /**
1177 * @brief This method provides READY state specific handling for
1178 * when a user attempts to start an internal request. If the high
1179 * priority IO is also internal, this method will schedule its timer.
1180 *
1181 * @param[in] controller This parameter specifies the controller object
1182 * on which the user is attempting to perform a start IO
1183 * operation.
1184 * @param[in] remote_device This parameter specifies the remote deivce
1185 * object on which the user is attempting to perform a start IO
1186 * operation.
1187 * @param[in] io_request This parameter specifies the IO request to be
1188 * started.
1189 * @param[in] io_tag This parameter specifies the optional allocated
1190 * IO tag. Please reference scif_controller_start_io() for
1191 * more information.
1192 *
1193 * @return This method returns an indication of whether the start IO
1194 * operation succeeded.
1195 * @retval SCI_SUCCESS This value is returned when the start IO operation
1196 * begins successfully.
1197 */
1198 static
1199 SCI_STATUS scif_sas_controller_ready_start_high_priority_io_handler(
1200 SCI_BASE_CONTROLLER_T * controller,
1201 SCI_BASE_REMOTE_DEVICE_T * remote_device,
1202 SCI_BASE_REQUEST_T * io_request,
1203 U16 io_tag
1204 )
1205 {
1206 SCI_STATUS status;
1207 SCIF_SAS_IO_REQUEST_T * fw_io = (SCIF_SAS_IO_REQUEST_T *)io_request;
1208
1209 SCIF_LOG_TRACE((
1210 sci_base_object_get_logger(controller),
1211 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST,
1212 "scif_sas_controller_ready_start_high_priority_io_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
1213 controller, remote_device, io_request, io_tag
1214 ));
1215
1216 status = scif_sas_controller_common_start_high_priority_io_handler(
1217 controller, remote_device, io_request, io_tag);
1218
1219 if (status == SCI_SUCCESS)
1220 {
1221 //External io could also be put in high priority queue. i.e. the
1222 //smp request for EA Target Reset.
1223 if (fw_io->parent.is_internal)
1224 {
1225 SCIF_SAS_INTERNAL_IO_REQUEST_T * fw_internal_io =
1226 (SCIF_SAS_INTERNAL_IO_REQUEST_T *)fw_io;
1227
1228 //start the timer for internal io
1229 scif_cb_timer_start(
1230 (SCI_CONTROLLER_HANDLE_T)controller,
1231 fw_internal_io->internal_io_timer,
1232 SCIF_SAS_INTERNAL_REQUEST_TIMEOUT
1233 );
1234 }
1235 }
1236 else
1237 {
1238 //If failed to start, most likely the device or domain is not in
1239 //correct state, and the IO has been cleaned up in controller's start
1240 //high priority IO handler. We should just continue to start the next
1241 //IO in the HP queue.
1242
1243 SCIF_LOG_TRACE((
1244 sci_base_object_get_logger(controller),
1245 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST,
1246 "scif_controller_start_high_priority_io(0x%x, 0x%x), starting io failed\n",
1247 controller, fw_io
1248 ));
1249 }
1250
1251 return status;
1252 }
1253
1254
1255 //******************************************************************************
1256 //* S T O P P I N G H A N D L E R S
1257 //******************************************************************************
1258 /**
1259 * @brief This method provides STOPPING state specific handling for
1260 * when a user attempts to start an internal request. Note that we don't
1261 * start the timer for internal IO during controller stopping state.
1262 *
1263 * @param[in] controller This parameter specifies the controller object
1264 * on which the user is attempting to perform a start IO
1265 * operation.
1266 * @param[in] remote_device This parameter specifies the remote deivce
1267 * object on which the user is attempting to perform a start IO
1268 * operation.
1269 * @param[in] io_request This parameter specifies the IO request to be
1270 * started.
1271 * @param[in] io_tag This parameter specifies the optional allocated
1272 * IO tag. Please reference scif_controller_start_io() for
1273 * more information.
1274 *
1275 * @return This method returns an indication of whether the start IO
1276 * operation succeeded.
1277 * @retval SCI_SUCCESS This value is returned when the start IO operation
1278 * begins successfully.
1279 */
1280 static
1281 SCI_STATUS scif_sas_controller_stopping_start_high_priority_io_handler(
1282 SCI_BASE_CONTROLLER_T * controller,
1283 SCI_BASE_REMOTE_DEVICE_T * remote_device,
1284 SCI_BASE_REQUEST_T * io_request,
1285 U16 io_tag
1286 )
1287 {
1288 SCIF_LOG_TRACE((
1289 sci_base_object_get_logger(controller),
1290 SCIF_LOG_OBJECT_CONTROLLER | SCIF_LOG_OBJECT_IO_REQUEST,
1291 "scif_sas_controller_stopping_start_high_priority_io_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
1292 controller, remote_device, io_request, io_tag
1293 ));
1294
1295 return scif_sas_controller_common_start_high_priority_io_handler(
1296 controller, remote_device, io_request, io_tag);
1297 }
1298
1299
1300 //******************************************************************************
1301 //* S T O P P E D H A N D L E R S
1302 //******************************************************************************
1303
1304 /**
1305 * @brief This method provides STOPPED state specific handling for
1306 * when a user attempts to reset a controller.
1307 *
1308 * @param[in] controller This parameter specifies the controller object
1309 * on which the user is attempting to perform a reset
1310 * operation.
1311 *
1312 * @return This method returns an indication of whether the reset operation
1313 * succeeded.
1314 * @retval SCI_SUCCESS This value is returned when the reset operation
1315 * completes successfully.
1316 */
1317 static
1318 SCI_STATUS scif_sas_controller_stopped_reset_handler(
1319 SCI_BASE_CONTROLLER_T * controller
1320 )
1321 {
1322 return scif_sas_controller_execute_reset((SCIF_SAS_CONTROLLER_T*)controller);
1323 }
1324
1325
1326 //******************************************************************************
1327 //* F A I L E D H A N D L E R S
1328 //******************************************************************************
1329
1330 /**
1331 * @brief This method provides FAILED state specific handling for
1332 * when a user attempts to reset a controller.
1333 *
1334 * @param[in] controller This parameter specifies the controller object
1335 * on which the user is attempting to perform a reset
1336 * operation.
1337 *
1338 * @return This method returns an indication of whether the reset operation
1339 * succeeded.
1340 * @retval SCI_SUCCESS This value is returned when the reset operation
1341 * completes successfully.
1342 */
1343 static
1344 SCI_STATUS scif_sas_controller_failed_reset_handler(
1345 SCI_BASE_CONTROLLER_T * controller
1346 )
1347 {
1348 return scif_sas_controller_execute_reset((SCIF_SAS_CONTROLLER_T*)controller);
1349 }
1350
1351 //******************************************************************************
1352 //* D E F A U L T H A N D L E R S
1353 //******************************************************************************
1354
1355 /**
1356 * @brief This method provides default handling (i.e. returns an error)
1357 * when a user attempts to start a controller and a start operation
1358 * is not allowed.
1359 *
1360 * @param[in] controller This parameter specifies the controller object
1361 * on which the user is attempting to perform a start operation.
1362 * @param[in] timeout This parameter specifies the timeout value (in
1363 * milliseconds) to be utilized for this operation.
1364 *
1365 * @return This method returns an indication that start operations are not
1366 * allowed.
1367 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1368 */
1369 static
1370 SCI_STATUS scif_sas_controller_default_start_handler(
1371 SCI_BASE_CONTROLLER_T * controller,
1372 U32 timeout
1373 )
1374 {
1375 SCIF_LOG_WARNING((
1376 sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller),
1377 SCIF_LOG_OBJECT_CONTROLLER,
1378 "Controller:0x%x State:0x%x invalid state to start controller.\n",
1379 controller,
1380 sci_base_state_machine_get_state(
1381 &((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine)
1382 ));
1383
1384 return SCI_FAILURE_INVALID_STATE;
1385 }
1386
1387 /**
1388 * @brief This method provides default handling (i.e. returns an error)
1389 * when a user attempts to stop a controller and a stop operation
1390 * is not allowed.
1391 *
1392 * @param[in] controller This parameter specifies the controller object
1393 * on which the user is attempting to perform a stop operation.
1394 * @param[in] timeout This parameter specifies the timeout value (in
1395 * milliseconds) to be utilized for this operation.
1396 *
1397 * @return This method returns an indication that stop operations are not
1398 * allowed.
1399 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1400 */
1401 static
1402 SCI_STATUS scif_sas_controller_default_stop_handler(
1403 SCI_BASE_CONTROLLER_T * controller,
1404 U32 timeout
1405 )
1406 {
1407 SCIF_LOG_WARNING((
1408 sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller),
1409 SCIF_LOG_OBJECT_CONTROLLER,
1410 "Controller:0x%x State:0x%x invalid state to stop controller.\n",
1411 controller,
1412 sci_base_state_machine_get_state(
1413 &((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine)
1414 ));
1415
1416 return SCI_FAILURE_INVALID_STATE;
1417 }
1418
1419 /**
1420 * @brief This method provides default handling (i.e. returns an error)
1421 * when a user attempts to reset a controller and a reset operation
1422 * is not allowed.
1423 *
1424 * @param[in] controller This parameter specifies the controller object
1425 * on which the user is attempting to perform a reset operation.
1426 *
1427 * @return This method returns an indication that reset operations are not
1428 * allowed.
1429 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1430 */
1431 static
1432 SCI_STATUS scif_sas_controller_default_reset_handler(
1433 SCI_BASE_CONTROLLER_T * controller
1434 )
1435 {
1436 SCIF_LOG_WARNING((
1437 sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller),
1438 SCIF_LOG_OBJECT_CONTROLLER,
1439 "Controller:0x%x State:0x%x invalid state to reset controller.\n",
1440 controller,
1441 sci_base_state_machine_get_state(
1442 &((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine)
1443 ));
1444
1445 return SCI_FAILURE_INVALID_STATE;
1446 }
1447
1448 /**
1449 * @brief This method provides default handling (i.e. returns an error)
1450 * when a user attempts to initialize a controller and an initialize
1451 * operation is not allowed.
1452 *
1453 * @param[in] controller This parameter specifies the controller object
1454 * on which the user is attempting to perform an initialize
1455 * operation.
1456 *
1457 * @return This method returns an indication that initialize operations
1458 * are not allowed.
1459 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1460 */
1461 static
1462 SCI_STATUS scif_sas_controller_default_initialize_handler(
1463 SCI_BASE_CONTROLLER_T * controller
1464 )
1465 {
1466 SCIF_LOG_WARNING((
1467 sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller),
1468 SCIF_LOG_OBJECT_CONTROLLER,
1469 "Controller:0x%x State:0x%x invalid state to initialize controller.\n",
1470 controller,
1471 sci_base_state_machine_get_state(
1472 &((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine)
1473 ));
1474
1475 return SCI_FAILURE_INVALID_STATE;
1476 }
1477
1478 /**
1479 * @brief This method provides default handling (i.e. returns an error)
1480 * when a user attempts to start an IO on a controller and a start
1481 * IO operation is not allowed.
1482 *
1483 * @param[in] controller This parameter specifies the controller object
1484 * on which the user is attempting to perform a start IO
1485 * operation.
1486 * @param[in] remote_device This parameter specifies the remote deivce
1487 * object on which the user is attempting to perform a start IO
1488 * operation.
1489 * @param[in] io_request This parameter specifies the IO request to be
1490 * started.
1491 * @param[in] io_tag This parameter specifies the optional allocated
1492 * IO tag. Please reference scif_controller_start_io() for
1493 * more information.
1494 *
1495 * @return This method returns an indication that start IO operations
1496 * are not allowed.
1497 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1498 */
1499 static
1500 SCI_STATUS scif_sas_controller_default_start_io_handler(
1501 SCI_BASE_CONTROLLER_T * controller,
1502 SCI_BASE_REMOTE_DEVICE_T * remote_device,
1503 SCI_BASE_REQUEST_T * io_request,
1504 U16 io_tag
1505 )
1506 {
1507 SCIF_LOG_WARNING((
1508 sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller),
1509 SCIF_LOG_OBJECT_CONTROLLER,
1510 "Controller:0x%x State:0x%x invalid state to start IO.\n",
1511 controller,
1512 sci_base_state_machine_get_state(
1513 &((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine)
1514 ));
1515
1516 return SCI_FAILURE_INVALID_STATE;
1517 }
1518
1519 /**
1520 * @brief This method provides default handling (i.e. returns an error)
1521 * when a user attempts to complete an IO on a controller and a
1522 * complete IO operation is not allowed.
1523 *
1524 * @param[in] controller This parameter specifies the controller object
1525 * on which the user is attempting to perform a complete IO
1526 * operation.
1527 * @param[in] remote_device This parameter specifies the remote deivce
1528 * object on which the user is attempting to perform a start IO
1529 * operation.
1530 * @param[in] io_request This parameter specifies the IO request to be
1531 * started.
1532 *
1533 * @return This method returns an indication that complete IO operations
1534 * are not allowed.
1535 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1536 */
1537 static
1538 SCI_STATUS scif_sas_controller_default_complete_io_handler(
1539 SCI_BASE_CONTROLLER_T * controller,
1540 SCI_BASE_REMOTE_DEVICE_T * remote_device,
1541 SCI_BASE_REQUEST_T * io_request
1542 )
1543 {
1544 SCIF_LOG_WARNING((
1545 sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller),
1546 SCIF_LOG_OBJECT_CONTROLLER,
1547 "Controller:0x%x State:0x%x invalid state to complete IO.\n",
1548 controller,
1549 sci_base_state_machine_get_state(
1550 &((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine)
1551 ));
1552
1553 return SCI_FAILURE_INVALID_STATE;
1554 }
1555
1556 /**
1557 * @brief This method provides default handling (i.e. returns an error)
1558 * when a user attempts to continue an IO on a controller and a
1559 * continue IO operation is not allowed.
1560 *
1561 * @param[in] controller This parameter specifies the controller object
1562 * on which the user is attempting to perform a continue IO
1563 * operation.
1564 * @param[in] remote_device This parameter specifies the remote deivce
1565 * object on which the user is attempting to perform a start IO
1566 * operation.
1567 * @param[in] io_request This parameter specifies the IO request to be
1568 * started.
1569 *
1570 * @return This method returns an indication that continue IO operations
1571 * are not allowed.
1572 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1573 */
1574 static
1575 SCI_STATUS scif_sas_controller_default_continue_io_handler(
1576 SCI_BASE_CONTROLLER_T * controller,
1577 SCI_BASE_REMOTE_DEVICE_T * remote_device,
1578 SCI_BASE_REQUEST_T * io_request
1579 )
1580 {
1581 SCIF_LOG_WARNING((
1582 sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller),
1583 SCIF_LOG_OBJECT_CONTROLLER,
1584 "Controller:0x%x State:0x%x invalid state to continue IO.\n",
1585 controller,
1586 sci_base_state_machine_get_state(
1587 &((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine)
1588 ));
1589
1590 return SCI_FAILURE_INVALID_STATE;
1591 }
1592
1593 /**
1594 * @brief This method provides default handling (i.e. returns an error)
1595 * when a user attempts to start a task on a controller and a start
1596 * task operation is not allowed.
1597 *
1598 * @param[in] controller This parameter specifies the controller object
1599 * on which the user is attempting to perform a start task
1600 * operation.
1601 * @param[in] remote_device This parameter specifies the remote deivce
1602 * object on which the user is attempting to perform a start
1603 * task operation.
1604 * @param[in] task_request This parameter specifies the task management
1605 * request to be started.
1606 * @param[in] io_tag This parameter specifies the optional allocated
1607 * IO tag. Please reference scif_controller_start_task() for
1608 * more information.
1609 *
1610 * @return This method returns an indication that start task operations
1611 * are not allowed.
1612 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1613 */
1614 static
1615 SCI_STATUS scif_sas_controller_default_start_task_handler(
1616 SCI_BASE_CONTROLLER_T * controller,
1617 SCI_BASE_REMOTE_DEVICE_T * remote_device,
1618 SCI_BASE_REQUEST_T * task_request,
1619 U16 io_tag
1620 )
1621 {
1622 SCIF_LOG_WARNING((
1623 sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller),
1624 SCIF_LOG_OBJECT_CONTROLLER,
1625 "Controller:0x%x State:0x%x invalid state to start task mgmt.\n",
1626 controller,
1627 sci_base_state_machine_get_state(
1628 &((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine)
1629 ));
1630
1631 return SCI_FAILURE_INVALID_STATE;
1632 }
1633
1634 /**
1635 * @brief This method provides default handling (i.e. returns an error)
1636 * when a user attempts to complete a task on a controller and a
1637 * complete task operation is not allowed.
1638 *
1639 * @param[in] controller This parameter specifies the controller object
1640 * on which the user is attempting to perform a complete task
1641 * operation.
1642 * @param[in] remote_device This parameter specifies the remote deivce
1643 * object on which the user is attempting to perform a start
1644 * task operation.
1645 * @param[in] task_request This parameter specifies the task management
1646 * request to be started.
1647 *
1648 * @return This method returns an indication that complete task operations
1649 * are not allowed.
1650 * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1651 */
1652 static
1653 SCI_STATUS scif_sas_controller_default_complete_task_handler(
1654 SCI_BASE_CONTROLLER_T * controller,
1655 SCI_BASE_REMOTE_DEVICE_T * remote_device,
1656 SCI_BASE_REQUEST_T * task_request
1657 )
1658 {
1659 SCIF_LOG_WARNING((
1660 sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller),
1661 SCIF_LOG_OBJECT_CONTROLLER,
1662 "Controller:0x%x State:0x%x invalid state to complete task mgmt.\n",
1663 controller,
1664 sci_base_state_machine_get_state(
1665 &((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine)
1666 ));
1667
1668 return SCI_FAILURE_INVALID_STATE;
1669 }
1670
1671 static
1672 SCI_STATUS scif_sas_controller_failed_state_start_io_handler(
1673 SCI_BASE_CONTROLLER_T * controller,
1674 SCI_BASE_REMOTE_DEVICE_T * remote_device,
1675 SCI_BASE_REQUEST_T * io_request,
1676 U16 io_tag
1677 )
1678 {
1679 SCIF_LOG_WARNING((
1680 sci_base_object_get_logger((SCIF_SAS_CONTROLLER_T *)controller),
1681 SCIF_LOG_OBJECT_CONTROLLER,
1682 "Controller:0x%x State:0x%x invalid state to start IO.\n",
1683 controller,
1684 sci_base_state_machine_get_state(
1685 &((SCIF_SAS_CONTROLLER_T *)controller)->parent.state_machine)
1686 ));
1687
1688 return SCI_FAILURE;
1689 }
1690
1691 #define scif_sas_controller_stopping_complete_io_handler \
1692 scif_sas_controller_ready_complete_io_handler
1693 #define scif_sas_controller_stopping_complete_task_handler \
1694 scif_sas_controller_ready_complete_task_handler
1695 #define scif_sas_controller_default_start_high_priority_io_handler \
1696 scif_sas_controller_default_start_io_handler
1697 #define scif_sas_controller_default_complete_high_priority_io_handler \
1698 scif_sas_controller_default_complete_io_handler
1699 #define scif_sas_controller_stopping_complete_high_priority_io_handler \
1700 scif_sas_controller_ready_complete_high_priority_io_handler
1701
1702
1703 SCI_BASE_CONTROLLER_STATE_HANDLER_T
1704 scif_sas_controller_state_handler_table[SCI_BASE_CONTROLLER_MAX_STATES] =
1705 {
1706 // SCI_BASE_CONTROLLER_STATE_INITIAL
1707 {
1708 scif_sas_controller_default_start_handler,
1709 scif_sas_controller_default_stop_handler,
1710 scif_sas_controller_default_reset_handler,
1711 scif_sas_controller_default_initialize_handler,
1712 scif_sas_controller_default_start_io_handler,
1713 scif_sas_controller_default_start_high_priority_io_handler,
1714 scif_sas_controller_default_complete_io_handler,
1715 scif_sas_controller_default_complete_high_priority_io_handler,
1716 scif_sas_controller_default_continue_io_handler,
1717 scif_sas_controller_default_start_task_handler,
1718 scif_sas_controller_default_complete_task_handler
1719 },
1720 // SCI_BASE_CONTROLLER_STATE_RESET
1721 {
1722 scif_sas_controller_default_start_handler,
1723 scif_sas_controller_default_stop_handler,
1724 scif_sas_controller_default_reset_handler,
1725 scif_sas_controller_reset_initialize_handler,
1726 scif_sas_controller_default_start_io_handler,
1727 scif_sas_controller_default_start_high_priority_io_handler,
1728 scif_sas_controller_default_complete_io_handler,
1729 scif_sas_controller_default_complete_high_priority_io_handler,
1730 scif_sas_controller_default_continue_io_handler,
1731 scif_sas_controller_default_start_task_handler,
1732 scif_sas_controller_default_complete_task_handler
1733 },
1734 // SCI_BASE_CONTROLLER_STATE_INITIALIZING
1735 {
1736 scif_sas_controller_default_start_handler,
1737 scif_sas_controller_default_stop_handler,
1738 scif_sas_controller_default_reset_handler,
1739 scif_sas_controller_default_initialize_handler,
1740 scif_sas_controller_default_start_io_handler,
1741 scif_sas_controller_default_start_high_priority_io_handler,
1742 scif_sas_controller_default_complete_io_handler,
1743 scif_sas_controller_default_complete_high_priority_io_handler,
1744 scif_sas_controller_default_continue_io_handler,
1745 scif_sas_controller_default_start_task_handler,
1746 scif_sas_controller_default_complete_task_handler
1747 },
1748 // SCI_BASE_CONTROLLER_STATE_INITIALIZED
1749 {
1750 scif_sas_controller_initialized_start_handler,
1751 scif_sas_controller_default_stop_handler,
1752 scif_sas_controller_default_reset_handler,
1753 scif_sas_controller_default_initialize_handler,
1754 scif_sas_controller_default_start_io_handler,
1755 scif_sas_controller_default_start_high_priority_io_handler,
1756 scif_sas_controller_default_complete_io_handler,
1757 scif_sas_controller_default_complete_high_priority_io_handler,
1758 scif_sas_controller_default_continue_io_handler,
1759 scif_sas_controller_default_start_task_handler,
1760 scif_sas_controller_default_complete_task_handler
1761 },
1762 // SCI_BASE_CONTROLLER_STATE_STARTING
1763 {
1764 scif_sas_controller_default_start_handler,
1765 scif_sas_controller_default_stop_handler,
1766 scif_sas_controller_default_reset_handler,
1767 scif_sas_controller_default_initialize_handler,
1768 scif_sas_controller_default_start_io_handler,
1769 scif_sas_controller_default_start_high_priority_io_handler,
1770 scif_sas_controller_default_complete_io_handler,
1771 scif_sas_controller_default_complete_high_priority_io_handler,
1772 scif_sas_controller_default_continue_io_handler,
1773 scif_sas_controller_default_start_task_handler,
1774 scif_sas_controller_default_complete_task_handler
1775 },
1776 // SCI_BASE_CONTROLLER_STATE_READY
1777 {
1778 scif_sas_controller_default_start_handler,
1779 scif_sas_controller_ready_stop_handler,
1780 scif_sas_controller_ready_reset_handler,
1781 scif_sas_controller_default_initialize_handler,
1782 scif_sas_controller_ready_start_io_handler,
1783 scif_sas_controller_ready_start_high_priority_io_handler,
1784 scif_sas_controller_ready_complete_io_handler,
1785 scif_sas_controller_ready_complete_high_priority_io_handler,
1786 scif_sas_controller_ready_continue_io_handler,
1787 scif_sas_controller_ready_start_task_handler,
1788 scif_sas_controller_ready_complete_task_handler
1789 },
1790 // SCI_BASE_CONTROLLER_STATE_RESETTING
1791 {
1792 scif_sas_controller_default_start_handler,
1793 scif_sas_controller_default_stop_handler,
1794 scif_sas_controller_default_reset_handler,
1795 scif_sas_controller_default_initialize_handler,
1796 scif_sas_controller_default_start_io_handler,
1797 scif_sas_controller_default_start_high_priority_io_handler,
1798 scif_sas_controller_default_complete_io_handler,
1799 scif_sas_controller_default_complete_high_priority_io_handler,
1800 scif_sas_controller_default_continue_io_handler,
1801 scif_sas_controller_default_start_task_handler,
1802 scif_sas_controller_default_complete_task_handler
1803 },
1804 // SCI_BASE_CONTROLLER_STATE_STOPPING
1805 {
1806 scif_sas_controller_default_start_handler,
1807 scif_sas_controller_default_stop_handler,
1808 scif_sas_controller_default_reset_handler,
1809 scif_sas_controller_default_initialize_handler,
1810 scif_sas_controller_default_start_io_handler,
1811 scif_sas_controller_stopping_start_high_priority_io_handler,
1812 scif_sas_controller_stopping_complete_io_handler,
1813 scif_sas_controller_stopping_complete_high_priority_io_handler,
1814 scif_sas_controller_default_continue_io_handler,
1815 scif_sas_controller_default_start_task_handler, /**@todo Allow in core?*/
1816 scif_sas_controller_stopping_complete_task_handler
1817 },
1818 // SCI_BASE_CONTROLLER_STATE_STOPPED
1819 {
1820 scif_sas_controller_default_start_handler,
1821 scif_sas_controller_default_stop_handler,
1822 scif_sas_controller_stopped_reset_handler,
1823 scif_sas_controller_default_initialize_handler,
1824 scif_sas_controller_default_start_io_handler,
1825 scif_sas_controller_default_start_high_priority_io_handler,
1826 scif_sas_controller_default_complete_io_handler,
1827 scif_sas_controller_default_complete_high_priority_io_handler,
1828 scif_sas_controller_default_continue_io_handler,
1829 scif_sas_controller_default_start_task_handler,
1830 scif_sas_controller_default_complete_task_handler
1831 },
1832 // SCI_BASE_CONTROLLER_STATE_FAILED
1833 {
1834 scif_sas_controller_default_start_handler,
1835 scif_sas_controller_default_stop_handler,
1836 scif_sas_controller_failed_reset_handler,
1837 scif_sas_controller_default_initialize_handler,
1838 scif_sas_controller_failed_state_start_io_handler,
1839 scif_sas_controller_failed_state_start_io_handler,
1840 scif_sas_controller_default_complete_io_handler,
1841 scif_sas_controller_default_complete_high_priority_io_handler,
1842 scif_sas_controller_default_continue_io_handler,
1843 scif_sas_controller_default_start_task_handler,
1844 scif_sas_controller_default_complete_task_handler
1845 }
1846 };
1847
Cache object: c7ea7e6405e3ebed262b9f814936c97c
|