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 
1848