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