xref: /freebsd/sys/dev/isci/scil/scif_sas_domain_state_handlers.c (revision ddd5b8e9b4d8957fce018c520657cdfa4ecffad3)
1 /*-
2  * This file is provided under a dual BSD/GPLv2 license.  When using or
3  * redistributing this file, you may do so under either license.
4  *
5  * GPL LICENSE SUMMARY
6  *
7  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of version 2 of the GNU General Public License as
11  * published by the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
21  * The full GNU General Public License is included in this distribution
22  * in the file called LICENSE.GPL.
23  *
24  * BSD LICENSE
25  *
26  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
27  * All rights reserved.
28  *
29  * Redistribution and use in source and binary forms, with or without
30  * modification, are permitted provided that the following conditions
31  * are met:
32  *
33  *   * Redistributions of source code must retain the above copyright
34  *     notice, this list of conditions and the following disclaimer.
35  *   * Redistributions in binary form must reproduce the above copyright
36  *     notice, this list of conditions and the following disclaimer in
37  *     the documentation and/or other materials provided with the
38  *     distribution.
39  *
40  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
41  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
42  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
43  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
44  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
45  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
46  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
47  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
48  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
49  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
50  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
51  */
52 
53 #include <sys/cdefs.h>
54 __FBSDID("$FreeBSD$");
55 
56 /**
57  * @file
58  *
59  * @brief This file contains all of the state handler routines for each
60  *        of the domain states defined by the SCI_BASE_DOMAIN state
61  *        machine.
62  * @note
63  *        - The discover method must be synchronized with the
64  *          controller's completion handler.  The OS specific driver
65  *          component is responsible for ensuring this occurs.  If the
66  *          discovery method is called from within the call
67  *          tree of the completion routine, then no action is necessary.
68  */
69 
70 
71 #include <dev/isci/scil/scic_port.h>
72 #include <dev/isci/scil/scic_io_request.h>
73 #include <dev/isci/scil/scif_sas_logger.h>
74 #include <dev/isci/scil/scif_sas_domain.h>
75 
76 //******************************************************************************
77 //* P R O T E C T E D   M E T H O D S
78 //******************************************************************************
79 
80 //******************************************************************************
81 //* S T A R T I N G   H A N D L E R S
82 //******************************************************************************
83 
84 static
85 SCI_STATUS scif_sas_domain_starting_port_ready_handler(
86    SCI_BASE_DOMAIN_T * domain
87 )
88 {
89    SCIF_LOG_TRACE((
90       sci_base_object_get_logger(domain),
91       SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
92       "scif_sas_domain_starting_port_ready_handler(0x%x) enter\n",
93       domain
94    ));
95 
96    // The domain was previously completely stopped.  Now that the port is
97    // ready we can transition the domain to the ready state.
98    sci_base_state_machine_change_state(
99       &domain->state_machine, SCI_BASE_DOMAIN_STATE_READY
100    );
101 
102    return SCI_SUCCESS;
103 }
104 
105 //******************************************************************************
106 //* R E A D Y   H A N D L E R S
107 //******************************************************************************
108 
109 /**
110  * @brief This method provides READY state specific handling for
111  *        when a user attempts to discover a domain.
112  *
113  * @param[in]  domain This parameter specifies the domain object
114  *             on which the user is attempting to perform a discover
115  *             operation.
116  *
117  * @return This method returns an indication of whether the discover operation
118  *         succeeded.
119  * @retval SCI_SUCCESSS This value is returned when the discover operation
120  *         begins successfully.
121  */
122 static
123 SCI_STATUS scif_sas_domain_ready_discover_handler(
124    SCI_BASE_DOMAIN_T * domain,
125    U32                 op_timeout,
126    U32                 device_timeout
127 )
128 {
129    SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *)domain;
130 
131    SCIF_LOG_TRACE((
132       sci_base_object_get_logger(domain),
133       SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
134       "scif_sas_domain_ready_discover_handler(0x%x, 0x%x, 0x%x) enter\n",
135       domain, op_timeout, device_timeout
136    ));
137 
138    fw_domain->operation.timeout        = op_timeout;
139    fw_domain->operation.device_timeout = device_timeout;
140    fw_domain->operation.status         = SCI_SUCCESS;
141 
142    scif_cb_timer_start(
143       fw_domain->controller,
144       fw_domain->operation.timer,
145       fw_domain->operation.timeout
146    );
147 
148    scif_sas_domain_transition_to_discovering_state(fw_domain);
149 
150    return fw_domain->operation.status;
151 }
152 
153 /**
154  * @brief This method provides READY state processing for reception of a
155  *        port NOT ready notification from the core.
156  *
157  * @param[in]  domain This parameter specifies the domain object
158  *             on which the core port has just come ready.
159  *
160  * @return
161  */
162 static
163 SCI_STATUS scif_sas_domain_ready_port_not_ready_handler(
164    SCI_BASE_DOMAIN_T * domain,
165    U32                 reason_code
166 )
167 {
168    SCIF_LOG_TRACE((
169       sci_base_object_get_logger(domain),
170       SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
171       "scif_sas_domain_ready_port_not_ready_handler(0x%x, 0x%x) enter\n",
172       domain,
173       reason_code
174    ));
175 
176    if (reason_code != SCIC_PORT_NOT_READY_HARD_RESET_REQUESTED)
177    {
178       // Change to the STOPPING state to cause existing request
179       // completions to be terminated and devices removed.
180       sci_base_state_machine_change_state(
181          &domain->state_machine, SCI_BASE_DOMAIN_STATE_STOPPING
182       );
183    }
184 
185    return SCI_SUCCESS;
186 }
187 
188 /**
189  * @brief This method provides READY state specific handling for
190  *        when a user attempts to start an IO request.
191  *
192  * @param[in]  domain This parameter specifies the domain object
193  *             on which the user is attempting to perform a start IO
194  *             operation.
195  * @param[in]  remote_device This parameter specifies the remote device
196  *             object on which the user is attempting to perform a start IO
197  *             operation.
198  * @param[in]  io_request This parameter specifies the io request that is
199  *             being started.
200  *
201  * @return This method returns an indication of whether the start IO
202  *         operation succeeded.
203  * @retval SCI_SUCCESS This value is returned when the start IO operation
204  *         begins successfully.
205  */
206 static
207 SCI_STATUS scif_sas_domain_ready_start_io_handler(
208    SCI_BASE_DOMAIN_T        * domain,
209    SCI_BASE_REMOTE_DEVICE_T * remote_device,
210    SCI_BASE_REQUEST_T       * io_request
211 )
212 {
213    SCIF_SAS_DOMAIN_T        * fw_domain  = (SCIF_SAS_DOMAIN_T*) domain;
214    SCIF_SAS_REMOTE_DEVICE_T * fw_device  = (SCIF_SAS_REMOTE_DEVICE_T*)
215                                            remote_device;
216    SCIF_SAS_REQUEST_T       * fw_request = (SCIF_SAS_REQUEST_T*) io_request;
217    SCI_STATUS                 status;
218 
219    SCIF_LOG_TRACE((
220       sci_base_object_get_logger(domain),
221       SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST,
222       "scif_sas_domain_ready_start_io_handler(0x%x, 0x%x, 0x%x) enter\n",
223       domain, remote_device, io_request
224    ));
225 
226    status = fw_device->state_handlers->parent.start_io_handler(
227                &fw_device->parent, &fw_request->parent
228             );
229 
230    if (status == SCI_SUCCESS)
231    {
232       // Add the IO to the list of outstanding requests on the domain.
233       sci_fast_list_insert_tail(
234          &fw_domain->request_list, &fw_request->list_element
235       );
236    }
237 
238    return status;
239 }
240 
241 /**
242  * @brief This method provides READY state specific handling for
243  *        when a user attempts to complete an IO request.
244  *
245  * @param[in]  domain This parameter specifies the domain object
246  *             on which the user is attempting to perform a complete IO
247  *             operation.
248  * @param[in]  remote_device This parameter specifies the remote device
249  *             object on which the user is attempting to perform a complete
250  *             IO operation.
251  * @param[in]  io_request This parameter specifies the io request that is
252  *             being completed.
253  *
254  * @return This method returns an indication of whether the complete IO
255  *         operation succeeded.
256  * @retval SCI_SUCCESS This value is returned when the complete IO operation
257  *         is successful.
258  */
259 static
260 SCI_STATUS scif_sas_domain_ready_complete_io_handler(
261    SCI_BASE_DOMAIN_T        * domain,
262    SCI_BASE_REMOTE_DEVICE_T * remote_device,
263    SCI_BASE_REQUEST_T       * io_request
264 )
265 {
266    SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
267                                           remote_device;
268    SCIF_SAS_REQUEST_T       * fw_request= (SCIF_SAS_REQUEST_T*) io_request;
269 
270    SCIF_LOG_TRACE((
271       sci_base_object_get_logger(domain),
272       SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST,
273       "scif_sas_domain_ready_complete_io_handler(0x%x, 0x%x, 0x%x) enter\n",
274       domain, remote_device, io_request
275    ));
276 
277    // Remove the IO from the list of outstanding requests on the domain.
278    sci_fast_list_remove_element(&fw_request->list_element);
279 
280    return fw_device->state_handlers->parent.complete_io_handler(
281              &fw_device->parent, &fw_request->parent
282           );
283 }
284 
285 /**
286  * @brief This method provides READY state specific handling for
287  *        when a user attempts to continue an IO request.
288  *
289  * @param[in]  domain This parameter specifies the domain object
290  *             on which the user is attempting to perform a continue IO
291  *             operation.
292  * @param[in]  remote_device This parameter specifies the remote device
293  *             object on which the user is attempting to perform a start IO
294  *             operation.
295  * @param[in]  io_request This parameter specifies the io request that is
296  *             being started.
297  *
298  * @return This method returns an indication of whether the continue IO
299  *         operation succeeded.
300  * @retval SCI_SUCCESS This value is returned when the continue IO operation
301  *         begins successfully.
302  */
303 static
304 SCI_STATUS scif_sas_domain_ready_continue_io_handler(
305    SCI_BASE_DOMAIN_T        * domain,
306    SCI_BASE_REMOTE_DEVICE_T * remote_device,
307    SCI_BASE_REQUEST_T       * io_request
308 )
309 {
310    SCIF_LOG_TRACE((
311       sci_base_object_get_logger(domain),
312       SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST,
313       "scif_sas_domain_ready_continue_io_handler(0x%x, 0x%x, 0x%x) enter\n",
314       domain, remote_device, io_request
315    ));
316 
317    /// @todo fix return code handling.
318    return SCI_FAILURE;
319 }
320 
321 /**
322  * @brief This method provides READY state specific handling for
323  *        when a user attempts to start a task request.
324  *
325  * @param[in]  domain This parameter specifies the domain object
326  *             on which the user is attempting to perform a start task
327  *             operation.
328  * @param[in]  remote_device This parameter specifies the remote device
329  *             object on which the user is attempting to perform a start IO
330  *             operation.
331  * @param[in]  task_request This parameter specifies the task request that
332  *             is being started.
333  *
334  * @return This method returns an indication of whether the start task
335  *         operation succeeded.
336  * @retval SCI_SUCCESS This value is returned when the start task operation
337  *         begins successfully.
338  */
339 static
340 SCI_STATUS scif_sas_domain_ready_start_task_handler(
341    SCI_BASE_DOMAIN_T        * domain,
342    SCI_BASE_REMOTE_DEVICE_T * remote_device,
343    SCI_BASE_REQUEST_T       * task_request
344 )
345 {
346    SCIF_SAS_DOMAIN_T        * fw_domain  = (SCIF_SAS_DOMAIN_T*) domain;
347    SCIF_SAS_REMOTE_DEVICE_T * fw_device  = (SCIF_SAS_REMOTE_DEVICE_T*)
348                                            remote_device;
349    SCIF_SAS_REQUEST_T       * fw_request = (SCIF_SAS_REQUEST_T*) task_request;
350    SCI_STATUS                 status;
351 
352    SCIF_LOG_TRACE((
353       sci_base_object_get_logger(domain),
354       SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
355       "scif_sas_domain_ready_start_task_handler(0x%x, 0x%x, 0x%x) enter\n",
356       domain, remote_device, task_request
357    ));
358 
359    status = fw_device->state_handlers->parent.start_task_handler(
360                &fw_device->parent, &fw_request->parent
361             );
362 
363    if (status == SCI_SUCCESS)
364    {
365       // Add the task to the list of outstanding requests on the domain.
366       sci_fast_list_insert_tail(
367          &fw_domain->request_list, &fw_request->list_element
368       );
369    }
370 
371    return status;
372 }
373 
374 /**
375  * @brief This method provides READY state specific handling for
376  *        when a user attempts to complete a task request.
377  *
378  * @param[in]  domain This parameter specifies the domain object
379  *             on which the user is attempting to perform a complete task
380  *             operation.
381  * @param[in]  remote_device This parameter specifies the remote device
382  *             object on which the user is attempting to perform a start IO
383  *             operation.
384  * @param[in]  task_request This parameter specifies the task request that
385  *             is being started.
386  *
387  * @return This method returns an indication of whether the complete task
388  *         operation succeeded.
389  * @retval SCI_SUCCESS This value is returned when the complete task operation
390  *         begins successfully.
391  */
392 static
393 SCI_STATUS scif_sas_domain_ready_complete_task_handler(
394    SCI_BASE_DOMAIN_T        * domain,
395    SCI_BASE_REMOTE_DEVICE_T * remote_device,
396    SCI_BASE_REQUEST_T       * task_request
397 )
398 {
399    SCIF_SAS_REMOTE_DEVICE_T * fw_device  = (SCIF_SAS_REMOTE_DEVICE_T*)
400                                            remote_device;
401    SCIF_SAS_REQUEST_T       * fw_request = (SCIF_SAS_REQUEST_T*) task_request;
402 
403    SCIF_LOG_TRACE((
404       sci_base_object_get_logger(domain),
405       SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
406       "scif_sas_domain_ready_complete_task_handler(0x%x, 0x%x, 0x%x) enter\n",
407       domain, remote_device, task_request
408    ));
409 
410    // Remove the IO from the list of outstanding requests on the domain.
411    sci_fast_list_remove_element(&fw_request->list_element);
412 
413    return fw_device->state_handlers->parent.complete_task_handler(
414              &fw_device->parent, &fw_request->parent
415           );
416 }
417 
418 
419 /**
420  * @brief This method provides READY state specific handling for when a user
421  *        attempts to start a high priority IO request.
422  *
423  * @param[in]  domain This parameter specifies the domain object
424  *             on which the user is attempting to perform a start high priority
425  *             IO operation (which is exclusively for Phy Control hard reset).
426  * @param[in]  remote_device This parameter specifies the remote device
427  *             object on which the user is attempting to perform a start
428  *             high priority IO operation.
429  * @param[in]  io_request This parameter specifies the io request that is
430  *             being started.
431  *
432  * @return This method returns an indication of whether the start IO
433  *         operation succeeded.
434  * @retval SCI_SUCCESS This value is returned when the start IO operation
435  *         begins successfully.
436  */
437 static
438 SCI_STATUS scif_sas_domain_ready_start_high_priority_io_handler(
439    SCI_BASE_DOMAIN_T        * domain,
440    SCI_BASE_REMOTE_DEVICE_T * remote_device,
441    SCI_BASE_REQUEST_T       * io_request
442 )
443 {
444    SCIF_SAS_DOMAIN_T        * fw_domain  = (SCIF_SAS_DOMAIN_T*) domain;
445    SCIF_SAS_REMOTE_DEVICE_T * fw_device  = (SCIF_SAS_REMOTE_DEVICE_T*)
446                                            remote_device;
447    SCIF_SAS_REQUEST_T       * fw_request = (SCIF_SAS_REQUEST_T*) io_request;
448    SCI_STATUS                 status;
449 
450    SCIF_LOG_TRACE((
451       sci_base_object_get_logger(domain),
452       SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST,
453       "scif_sas_domain_ready_start_high_priority_request_handler(0x%x, 0x%x, 0x%x) enter\n",
454       domain, remote_device, io_request
455    ));
456 
457    status = fw_device->state_handlers->start_high_priority_io_handler(
458                &fw_device->parent, &fw_request->parent
459             );
460 
461    if (status == SCI_SUCCESS)
462    {
463       // Add the IO to the list of outstanding requests on the domain.
464 
465       // When domain is in READY state, this high priority io is likely
466       // a smp Phy Control or Discover request sent to parent device of
467       // a target device, which is to be Target Reset. This high priority
468       // IO's probably has already been added to the domain's list as a
469       // SCIF_SAS_TASK_REQUEST. We need to check if it is already on the
470       // list.
471 
472       if ( ! sci_fast_list_is_on_this_list(
473                 &fw_domain->request_list, &fw_request->list_element))
474 
475          sci_fast_list_insert_tail(
476             &fw_domain->request_list, &fw_request->list_element
477          );
478    }
479 
480    return status;
481 }
482 
483 
484 /**
485  * @brief This method provides READY state specific handling for
486  *        when a user attempts to complete an high priroity IO request.
487  *
488  * @param[in]  domain This parameter specifies the domain object
489  *             on which the user is attempting to perform a complete high
490  *             priority IO operation (which is exclusively for Phy Control
491  *             hard reset).
492  * @param[in]  remote_device This parameter specifies the remote device
493  *             object on which the user is attempting to perform a complete
494  *             IO operation.
495  * @param[in]  io_request This parameter specifies the io request that is
496  *             being completed.
497  *
498  * @return This method returns an indication of whether the complete IO
499  *         operation succeeded.
500  * @retval SCI_SUCCESS This value is returned when the complete IO operation
501  *         is successful.
502  */
503 static
504 SCI_STATUS scif_sas_domain_ready_complete_high_priority_io_handler(
505    SCI_BASE_DOMAIN_T        * domain,
506    SCI_BASE_REMOTE_DEVICE_T * remote_device,
507    SCI_BASE_REQUEST_T       * io_request,
508    void                     * response_data,
509    SCI_IO_STATUS              completion_status
510 )
511 {
512    SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
513                                           remote_device;
514    SCIF_SAS_REQUEST_T       * fw_request= (SCIF_SAS_REQUEST_T*) io_request;
515 
516    SCIC_TRANSPORT_PROTOCOL    protocol;
517 
518    SCIF_LOG_TRACE((
519       sci_base_object_get_logger(domain),
520       SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST,
521       "scif_sas_domain_ready_complete_high_priority_io_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
522       domain, remote_device, io_request, response_data
523    ));
524 
525    protocol = scic_io_request_get_protocol(fw_request->core_object);
526 
527    // If the request is an SMP HARD/LINK RESET request, then the request
528    // came through the task management path (partially).  As a result,
529    // the accounting for the request is managed in the task request
530    // completion path.  Thus, only change the domain request counter if
531    // the request is not an SMP target reset of some sort.
532    if (
533          (protocol != SCIC_SMP_PROTOCOL)
534       || (fw_device->protocol_device.smp_device.current_activity !=
535                 SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_TARGET_RESET)
536       )
537    {
538       sci_fast_list_remove_element(&fw_request->list_element);
539    }
540 
541    return fw_device->state_handlers->complete_high_priority_io_handler(
542              &fw_device->parent, &fw_request->parent, response_data, completion_status
543           );
544 }
545 
546 //******************************************************************************
547 //* S T O P P I N G   H A N D L E R S
548 //******************************************************************************
549 
550 static
551 SCI_STATUS scif_sas_domain_stopping_device_stop_complete_handler(
552    SCI_BASE_DOMAIN_T        * domain,
553    SCI_BASE_REMOTE_DEVICE_T * remote_device
554 )
555 {
556    SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *) domain;
557 
558    SCIF_LOG_TRACE((
559       sci_base_object_get_logger(domain),
560       SCIF_LOG_OBJECT_DOMAIN,
561       "scif_sas_domain_stopping_device_stop_complete_handler(0x%x, 0x%x) enter\n",
562       domain, remote_device
563    ));
564 
565    // Attempt to transition to the stopped state.
566    scif_sas_domain_transition_to_stopped_state(fw_domain);
567 
568    return SCI_SUCCESS;
569 }
570 
571 /**
572  * @brief This method provides STOPPING state specific handling for
573  *        when a user attempts to complete an IO request.
574  *
575  * @param[in]  domain This parameter specifies the domain object
576  *             on which the user is attempting to perform a complete IO
577  *             operation.
578  * @param[in]  remote_device This parameter specifies the remote device
579  *             object on which the user is attempting to perform a complete
580  *             IO operation.
581  * @param[in]  io_request This parameter specifies the io request that is
582  *             being completed.
583  *
584  * @return This method returns an indication of whether the complete IO
585  *         operation succeeded.
586  * @retval SCI_SUCCESS This value is returned when the complete IO operation
587  *         is successful.
588  */
589 static
590 SCI_STATUS scif_sas_domain_stopping_complete_io_handler(
591    SCI_BASE_DOMAIN_T        * domain,
592    SCI_BASE_REMOTE_DEVICE_T * remote_device,
593    SCI_BASE_REQUEST_T       * io_request
594 )
595 {
596    SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *) domain;
597    SCI_STATUS          status;
598 
599    SCIF_LOG_TRACE((
600       sci_base_object_get_logger(domain),
601       SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST,
602       "scif_sas_domain_stopping_complete_io_handler(0x%x, 0x%x, 0x%x) enter\n",
603       domain, remote_device, io_request
604    ));
605 
606    status = scif_sas_domain_ready_complete_io_handler(
607                domain, remote_device, io_request
608             );
609 
610    // Attempt to transition to the stopped state.
611    scif_sas_domain_transition_to_stopped_state(fw_domain);
612 
613    return status;
614 }
615 
616 
617 /**
618  * @brief This method provides STOPPING state specific handling for
619  *        when a user attempts to complete an IO request.
620  *
621  * @param[in]  domain This parameter specifies the domain object
622  *             on which the user is attempting to perform a complete IO
623  *             operation.
624  * @param[in]  remote_device This parameter specifies the remote device
625  *             object on which the user is attempting to perform a complete
626  *             IO operation.
627  * @param[in]  io_request This parameter specifies the io request that is
628  *             being completed.
629  *
630  * @return This method returns an indication of whether the complete IO
631  *         operation succeeded.
632  * @retval SCI_SUCCESS This value is returned when the complete IO operation
633  *         is successful.
634  */
635 static
636 SCI_STATUS scif_sas_domain_stopping_complete_high_priority_io_handler(
637    SCI_BASE_DOMAIN_T        * domain,
638    SCI_BASE_REMOTE_DEVICE_T * remote_device,
639    SCI_BASE_REQUEST_T       * io_request,
640    void                     * response_data,
641    SCI_IO_STATUS              completion_status
642 )
643 {
644    SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *) domain;
645    SCI_STATUS          status;
646 
647    SCIF_LOG_TRACE((
648       sci_base_object_get_logger(domain),
649       SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST,
650       "scif_sas_domain_stopping_complete_io_handler(0x%x, 0x%x, 0x%x) enter\n",
651       domain, remote_device, io_request
652    ));
653 
654    status = scif_sas_domain_ready_complete_high_priority_io_handler(
655                domain, remote_device, io_request, response_data, completion_status
656             );
657 
658    // Attempt to transition to the stopped state.
659    scif_sas_domain_transition_to_stopped_state(fw_domain);
660 
661    return status;
662 }
663 
664 
665 /**
666  * @brief This method provides STOPPING state specific handling for
667  *        when a user attempts to complete a task request.
668  *
669  * @param[in]  domain This parameter specifies the domain object
670  *             on which the user is attempting to perform a complete task
671  *             operation.
672  *
673  * @return This method returns an indication of whether the complete task
674  *         operation succeeded.
675  * @retval SCI_SUCCESS This value is returned when the complete task operation
676  *         begins successfully.
677  */
678 static
679 SCI_STATUS scif_sas_domain_stopping_complete_task_handler(
680    SCI_BASE_DOMAIN_T        * domain,
681    SCI_BASE_REMOTE_DEVICE_T * remote_device,
682    SCI_BASE_REQUEST_T       * task_request
683 )
684 {
685    SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *) domain;
686    SCI_STATUS          status;
687 
688    SCIF_LOG_TRACE((
689       sci_base_object_get_logger(domain),
690       SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
691       "scif_sas_domain_stopping_complete_task_handler(0x%x, 0x%x, 0x%x) enter\n",
692       domain, remote_device, task_request
693    ));
694 
695    status = scif_sas_domain_ready_complete_task_handler(
696                domain, remote_device, task_request
697             );
698 
699    // Attempt to transition to the stopped state.
700    scif_sas_domain_transition_to_stopped_state(fw_domain);
701 
702    return SCI_SUCCESS;
703 }
704 
705 //******************************************************************************
706 //* D I S C O V E R I N G   H A N D L E R S
707 //******************************************************************************
708 
709 /**
710  * @brief This method provides DISCOVERING state specific processing for
711  *        reception of a port NOT ready notification from the core.  A port
712  *        NOT ready notification forces the discovery operation to complete
713  *        in error.  Additionally, all IOs are aborted and devices removed.
714  *
715  * @param[in]  domain This parameter specifies the domain object
716  *             for which the core port is no longer ready.
717  *
718  * @return
719  */
720 static
721 SCI_STATUS scif_sas_domain_discovering_port_not_ready_handler(
722    SCI_BASE_DOMAIN_T * domain,
723    U32                 reason_code
724 )
725 {
726    SCIF_LOG_TRACE((
727       sci_base_object_get_logger(domain),
728       SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
729       "scif_sas_domain_discovering_port_not_ready_handler(0x%x, 0x%x) enter\n",
730       domain,
731       reason_code
732    ));
733 
734    // Change to the STOPPING state to cause existing request
735    // completions to be terminated and devices removed.
736    sci_base_state_machine_change_state(
737       &domain->state_machine, SCI_BASE_DOMAIN_STATE_STOPPING
738    );
739 
740    return SCI_SUCCESS;
741 }
742 
743 static
744 SCI_STATUS scif_sas_domain_discovering_device_start_complete_handler(
745    SCI_BASE_DOMAIN_T        * domain,
746    SCI_BASE_REMOTE_DEVICE_T * remote_device
747 )
748 {
749    SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *)domain;
750 
751    SCIF_LOG_TRACE((
752       sci_base_object_get_logger(domain),
753       SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
754       "scif_sas_domain_discovering_device_start_complete_handler(0x%x) enter\n",
755       domain, remote_device
756    ));
757 
758    //domain will decide what's next step.
759    scif_sas_domain_continue_discover(fw_domain);
760 
761    return SCI_SUCCESS;
762 }
763 
764 // ---------------------------------------------------------------------------
765 
766 static
767 SCI_STATUS scif_sas_domain_discovering_device_stop_complete_handler(
768    SCI_BASE_DOMAIN_T        * domain,
769    SCI_BASE_REMOTE_DEVICE_T * remote_device
770 )
771 {
772    SCIF_LOG_TRACE((
773       sci_base_object_get_logger(domain),
774       SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
775       "scif_sas_domain_discovering_device_stop_complete_handler(0x%x) enter\n",
776       domain, remote_device
777    ));
778 
779    return SCI_FAILURE;
780 }
781 
782 
783 /**
784  * @brief This method provides DISCOVERING state specific handling for when a user
785  *        attempts to start a high priority IO request.
786  *
787  * @param[in]  domain This parameter specifies the domain object
788  *             on which the user is attempting to perform a start IO
789  *             operation.
790  * @param[in]  remote_device This parameter specifies the remote device
791  *             object on which the user is attempting to perform a start IO
792  *             operation.
793  * @param[in]  io_request This parameter specifies the io request that is
794  *             being started.
795  *
796  * @return This method returns an indication of whether the start IO
797  *         operation succeeded.
798  * @retval SCI_SUCCESS This value is returned when the start IO operation
799  *         begins successfully.
800  */
801 static
802 SCI_STATUS scif_sas_domain_discovering_start_high_priority_io_handler(
803    SCI_BASE_DOMAIN_T        * domain,
804    SCI_BASE_REMOTE_DEVICE_T * remote_device,
805    SCI_BASE_REQUEST_T       * io_request
806 )
807 {
808    SCIF_SAS_DOMAIN_T        * fw_domain  = (SCIF_SAS_DOMAIN_T*) domain;
809    SCIF_SAS_REMOTE_DEVICE_T * fw_device  = (SCIF_SAS_REMOTE_DEVICE_T*)
810                                            remote_device;
811    SCIF_SAS_REQUEST_T       * fw_request = (SCIF_SAS_REQUEST_T*) io_request;
812    SCI_STATUS                 status;
813 
814    SCIF_LOG_TRACE((
815       sci_base_object_get_logger(domain),
816       SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST,
817       "scif_sas_domain_discovery_start_high_priority_request_handler(0x%x, 0x%x, 0x%x) enter\n",
818       domain, remote_device, io_request
819    ));
820 
821    status = fw_device->state_handlers->start_high_priority_io_handler(
822                &fw_device->parent, &fw_request->parent
823             );
824 
825    if (status == SCI_SUCCESS)
826    {
827       // Add the IO to the list of outstanding requests on the domain.
828 
829       // It is possible this high priority IO's has already been added to
830       // the domain's list as a SCIF_SAS_TASK_REQUEST. We need to check
831       // if it is already on the list.
832       if ( ! sci_fast_list_is_on_this_list(
833                &fw_domain->request_list, &fw_request->list_element))
834 
835          sci_fast_list_insert_tail(
836             &fw_domain->request_list, &fw_request->list_element
837          );
838    }
839 
840    return status;
841 }
842 
843 
844 /**
845  * @brief This method provides DISCOVERING state specific handling for
846  *        when a user attempts to complete an IO request.  User IOs are
847  *        allowed to be completed during discovery.
848  *
849  * @param[in]  domain This parameter specifies the domain object
850  *             on which the user is attempting to perform a complete IO
851  *             operation.
852  * @param[in]  remote_device This parameter specifies the remote device
853  *             object on which the user is attempting to perform a complete
854  *             IO operation.
855  * @param[in]  io_request This parameter specifies the io request that is
856  *             being completed.
857  *
858  * @return This method returns an indication of whether the complete IO
859  *         operation succeeded.
860  * @retval SCI_SUCCESS This value is returned when the complete IO operation
861  *         is successful.
862  */
863 static
864 SCI_STATUS scif_sas_domain_discovering_complete_io_handler(
865    SCI_BASE_DOMAIN_T        * domain,
866    SCI_BASE_REMOTE_DEVICE_T * remote_device,
867    SCI_BASE_REQUEST_T       * io_request
868 )
869 {
870    SCIF_LOG_TRACE((
871       sci_base_object_get_logger(domain),
872       SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST,
873       "scif_sas_domain_discovering_complete_io_handler(0x%x, 0x%x, 0x%x) enter\n",
874       domain, remote_device, io_request
875    ));
876 
877    return scif_sas_domain_ready_complete_io_handler(
878              domain, remote_device, io_request
879           );
880 }
881 
882 /**
883  * @brief This method provides DISCOVERING state specific handling for
884  *        when a user attempts to complete an high priroity IO request.  User
885  *        IOs are allowed to be completed during discovery.
886  *
887  * @param[in]  domain This parameter specifies the domain object
888  *             on which the user is attempting to perform a complete IO
889  *             operation.
890  * @param[in]  remote_device This parameter specifies the remote device
891  *             object on which the user is attempting to perform a complete
892  *             IO operation.
893  * @param[in]  io_request This parameter specifies the io request that is
894  *             being completed.
895  *
896  * @return This method returns an indication of whether the complete IO
897  *         operation succeeded.
898  * @retval SCI_SUCCESS This value is returned when the complete IO operation
899  *         is successful.
900  */
901 static
902 SCI_STATUS scif_sas_domain_discovering_complete_high_priority_io_handler(
903    SCI_BASE_DOMAIN_T        * domain,
904    SCI_BASE_REMOTE_DEVICE_T * remote_device,
905    SCI_BASE_REQUEST_T       * io_request,
906    void                     * response_data,
907    SCI_IO_STATUS              completion_status
908 )
909 {
910    SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
911                                           remote_device;
912    SCIF_SAS_REQUEST_T       * fw_request= (SCIF_SAS_REQUEST_T*) io_request;
913 
914    SCIC_TRANSPORT_PROTOCOL    protocol;
915 
916    SCIF_LOG_TRACE((
917       sci_base_object_get_logger(domain),
918       SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST,
919       "scif_sas_domain_discovering_complete_high_priority_io_handler(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
920       domain, remote_device, io_request, response_data
921    ));
922 
923    protocol = scic_io_request_get_protocol(fw_request->core_object);
924 
925    // Remove the IO from the list of outstanding requests on the domain.
926 
927    // If the request is an SMP HARD/LINK RESET request, then the request
928    // came through the task management path (partially).  As a result,
929    // the accounting for the request is managed in the task request
930    // completion path.  Thus, only change the domain request counter if
931    // the request is not an SMP target reset of some sort.
932    if (
933          (protocol != SCIC_SMP_PROTOCOL)
934       || (fw_device->protocol_device.smp_device.current_activity !=
935                 SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_TARGET_RESET)
936    )
937    {
938       sci_fast_list_remove_element(&fw_request->list_element);
939    }
940 
941    return fw_device->state_handlers->complete_high_priority_io_handler(
942              &fw_device->parent, &fw_request->parent, response_data, completion_status
943           );
944 }
945 
946 
947 /**
948  * @brief This method provides DISCOVERING state specific handling for
949  *        when the framework attempts to complete an IO request.  Internal
950  *        Framework IOs allowed to be continued during discovery.
951  *
952  * @param[in]  domain This parameter specifies the domain object
953  *             on which the user is attempting to perform a continue IO
954  *             operation.
955  * @param[in]  remote_device This parameter specifies the remote device
956  *             object on which the user is attempting to perform a continue
957  *             IO operation.
958  * @param[in]  io_request This parameter specifies the io request that is
959  *             being continued.
960  *
961  * @return This method returns an indication of whether the continue IO
962  *         operation succeeded.
963  * @retval SCI_SUCCESS This value is returned when the continue IO operation
964  *         is successful.
965  */
966 static
967 SCI_STATUS scif_sas_domain_discovering_continue_io_handler(
968    SCI_BASE_DOMAIN_T        * domain,
969    SCI_BASE_REMOTE_DEVICE_T * remote_device,
970    SCI_BASE_REQUEST_T       * io_request
971 )
972 {
973    SCIF_LOG_TRACE((
974       sci_base_object_get_logger(domain),
975       SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_IO_REQUEST,
976       "scif_sas_domain_discovering_continue_io_handler(0x%x, 0x%x, 0x%x) enter\n",
977       domain, remote_device, io_request
978    ));
979 
980    /// @todo fix return code handling.
981    return SCI_FAILURE;
982 }
983 
984 
985 /**
986  * @brief This method provides handling when a user attempts to start
987  *        a task on a domain in DISCOVER state, only hard reset is allowed.
988  *
989  * @param[in]  domain This parameter specifies the domain object
990  *             on which the user is attempting to perform a start task
991  *             operation.
992  * @param[in]  remote_device This parameter specifies the remote device
993  *             object on which the user is attempting to perform a start IO
994  *             operation.
995  * @param[in]  task_request This parameter specifies the task request that
996  *             is being started.
997  *
998  * @return This method returns a status of start task operations
999  * @retval SCI_FAILURE_INVALID_STATE This value is returned for any tasks,
1000  *         except for HARD RESET.
1001  */
1002 static
1003 SCI_STATUS scif_sas_domain_discovering_start_task_handler(
1004    SCI_BASE_DOMAIN_T        * domain,
1005    SCI_BASE_REMOTE_DEVICE_T * remote_device,
1006    SCI_BASE_REQUEST_T       * task_request
1007 )
1008 {
1009    SCIF_SAS_REMOTE_DEVICE_T * fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
1010                                           remote_device;
1011    SCIF_SAS_TASK_REQUEST_T  * fw_task = (SCIF_SAS_TASK_REQUEST_T*)task_request;
1012 
1013    //Only let target reset go through.
1014    if (scif_sas_task_request_get_function(fw_task)
1015              == SCI_SAS_HARD_RESET)
1016    {
1017       //If the domain is in the middle of smp DISCOVER process,
1018       //interrupt it. After target reset is done, resume the smp DISCOVERY.
1019       scif_sas_domain_cancel_smp_activities(fw_device->domain);
1020 
1021       return scif_sas_domain_ready_start_task_handler(domain, remote_device, task_request);
1022    }
1023    else{
1024       SCIF_LOG_WARNING((
1025          sci_base_object_get_logger(domain),
1026          SCIF_LOG_OBJECT_DOMAIN,
1027          "Domain:0x%x Device:0x%x State:0x%x start task message invalid\n",
1028          domain, remote_device,
1029          sci_base_state_machine_get_state(&domain->state_machine)
1030       ));
1031 
1032       return SCI_FAILURE_INVALID_STATE;
1033    }
1034 }
1035 
1036 
1037 /**
1038  * @brief This method provides DISCOVERING state specific handling for
1039  *        when a user attempts to complete a task request.  User task
1040  *        management requests are allowed to be completed during discovery.
1041  *
1042  * @param[in]  domain This parameter specifies the domain object
1043  *             on which the user is attempting to perform a complete IO
1044  *             operation.
1045  * @param[in]  remote_device This parameter specifies the remote device
1046  *             object on which the user is attempting to perform a complete
1047  *             IO operation.
1048  * @param[in]  task_request This parameter specifies the task request that
1049  *             is being completed.
1050  *
1051  * @return This method returns an indication of whether the complete task
1052  *         management operation succeeded.
1053  * @retval SCI_SUCCESS This value is returned when the complete task request
1054  *         is successful.
1055  */
1056 static
1057 SCI_STATUS scif_sas_domain_discovering_complete_task_handler(
1058    SCI_BASE_DOMAIN_T        * domain,
1059    SCI_BASE_REMOTE_DEVICE_T * remote_device,
1060    SCI_BASE_REQUEST_T       * task_request
1061 )
1062 {
1063    SCI_STATUS status;
1064 
1065    SCIF_LOG_TRACE((
1066       sci_base_object_get_logger(domain),
1067       SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
1068       "scif_sas_domain_discovering_complete_task_handler(0x%x, 0x%x, 0x%x) enter\n",
1069       domain, remote_device, task_request
1070    ));
1071 
1072    status = scif_sas_domain_ready_complete_task_handler(
1073                domain, remote_device, task_request
1074             );
1075 
1076    return status;
1077 }
1078 
1079 //******************************************************************************
1080 //* D E F A U L T   H A N D L E R S
1081 //******************************************************************************
1082 
1083 /**
1084  * @brief This method provides default handling (i.e. returns an error)
1085  *        when a user attempts to discover a domain and a discovery
1086  *        operation is not allowed.
1087  *
1088  * @param[in]  domain This parameter specifies the domain object
1089  *             on which the user is attempting to perform an discover
1090  *             operation.
1091  * @param[in]  op_timeout This parameter specifies the timeout
1092  *             (in milliseconds) for the entire discovery operation.
1093  *             This timeout value should be some multiple of the
1094  *             individual device_timeout value.
1095  * @param[in]  device_timeout This parameter specifies the timeout
1096  *             (in milliseconds) for an individual device being discovered
1097  *             and configured during this operation.
1098  *
1099  * @return This method returns an indication that discovery operations
1100  *         are not allowed.
1101  * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1102  */
1103 static
1104 SCI_STATUS scif_sas_domain_default_discover_handler(
1105    SCI_BASE_DOMAIN_T * domain,
1106    U32                 op_timeout,
1107    U32                 device_timeout
1108 )
1109 {
1110    SCIF_LOG_WARNING((
1111       sci_base_object_get_logger((SCIF_SAS_DOMAIN_T *)domain),
1112       SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
1113       "Domain:0x%x State:0x%x requested to discover in invalid state\n",
1114       domain,
1115       sci_base_state_machine_get_state(&domain->state_machine)
1116    ));
1117 
1118    return SCI_FAILURE_INVALID_STATE;
1119 }
1120 
1121 /**
1122  * @brief This method provides default processing for reception of a port
1123  *        ready notification from the core.
1124  *
1125  * @param[in]  domain This parameter specifies the domain object
1126  *             on which the core port has just come ready.
1127  *
1128  * @return
1129  */
1130 static
1131 SCI_STATUS scif_sas_domain_default_port_ready_handler(
1132    SCI_BASE_DOMAIN_T * domain
1133 )
1134 {
1135    SCIF_LOG_INFO((
1136       sci_base_object_get_logger(domain),
1137       SCIF_LOG_OBJECT_DOMAIN,
1138       "Domain:0x%x State:0x%x port now ready\n",
1139       domain,
1140       sci_base_state_machine_get_state(&domain->state_machine)
1141    ));
1142 
1143    return SCI_SUCCESS;
1144 }
1145 
1146 /**
1147  * @brief This method provides default processing for reception of a port
1148  *        NOT ready notification from the core.
1149  *
1150  * @param[in]  domain This parameter specifies the domain object
1151  *             on which the core port has just come ready.
1152  *
1153  * @return
1154  */
1155 static
1156 SCI_STATUS scif_sas_domain_default_port_not_ready_handler(
1157    SCI_BASE_DOMAIN_T * domain,
1158    U32                 reason_code
1159 )
1160 {
1161    SCIF_LOG_WARNING((
1162       sci_base_object_get_logger(domain),
1163       SCIF_LOG_OBJECT_DOMAIN,
1164       "Domain:0x%x State:0x%x Port Not Ready 0x%x in invalid state\n",
1165       domain,
1166       sci_base_state_machine_get_state(&domain->state_machine),
1167       reason_code
1168    ));
1169 
1170    return SCI_FAILURE_INVALID_STATE;
1171 }
1172 
1173 /**
1174  * @brief This method provides default handling (i.e. returns an error)
1175  *        when a user attempts to start an IO on a domain and a start
1176  *        IO operation is not allowed.
1177  *
1178  * @param[in]  domain This parameter specifies the domain object
1179  *             on which the user is attempting to perform a start IO
1180  *             operation.
1181  * @param[in]  remote_device This parameter specifies the remote device
1182  *             object on which the user is attempting to perform a start IO
1183  *             operation.
1184  * @param[in]  io_request This parameter specifies the io request that is
1185  *             being started.
1186  *
1187  * @return This method returns an indication that start IO operations
1188  *         are not allowed.
1189  * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1190  */
1191 static
1192 SCI_STATUS scif_sas_domain_default_start_io_handler(
1193    SCI_BASE_DOMAIN_T        * domain,
1194    SCI_BASE_REMOTE_DEVICE_T * remote_device,
1195    SCI_BASE_REQUEST_T       * io_request
1196 )
1197 {
1198    SCIF_LOG_WARNING((
1199       sci_base_object_get_logger(domain),
1200       SCIF_LOG_OBJECT_DOMAIN,
1201       "Domain:0x%x Device:0x%x State:0x%x start IO message invalid\n",
1202       domain, remote_device,
1203       sci_base_state_machine_get_state(&domain->state_machine)
1204    ));
1205 
1206    return SCI_FAILURE_INVALID_STATE;
1207 }
1208 
1209 /**
1210  * @brief This method provides default handling (i.e. returns an error)
1211  *        when a user attempts to complete an IO on a domain and a
1212  *        complete IO operation is not allowed.
1213  *
1214  * @param[in]  domain This parameter specifies the domain object
1215  *             on which the user is attempting to perform a complete IO
1216  *             operation.
1217  * @param[in]  remote_device This parameter specifies the remote device
1218  *             object on which the user is attempting to perform a complete IO
1219  *             operation.
1220  * @param[in]  io_request This parameter specifies the io request that is
1221  *             being completed.
1222  *
1223  * @return This method returns an indication that complete IO operations
1224  *         are not allowed.
1225  * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1226  */
1227 static
1228 SCI_STATUS scif_sas_domain_default_complete_io_handler(
1229    SCI_BASE_DOMAIN_T        * domain,
1230    SCI_BASE_REMOTE_DEVICE_T * remote_device,
1231    SCI_BASE_REQUEST_T       * io_request
1232 )
1233 {
1234    SCIF_LOG_WARNING((
1235       sci_base_object_get_logger(domain),
1236       SCIF_LOG_OBJECT_DOMAIN,
1237       "Domain:0x%x Device:0x%x State:0x%x complete IO message invalid\n",
1238       domain, remote_device,
1239       sci_base_state_machine_get_state(&domain->state_machine)
1240    ));
1241 
1242    return SCI_FAILURE_INVALID_STATE;
1243 }
1244 
1245 
1246 /**
1247  * @brief This method provides default handling (i.e. returns an error)
1248  *        when a user attempts to complete an IO on a domain and a
1249  *        complete IO operation is not allowed.
1250  *
1251  * @param[in]  domain This parameter specifies the domain object
1252  *             on which the user is attempting to perform a complete IO
1253  *             operation.
1254  * @param[in]  remote_device This parameter specifies the remote device
1255  *             object on which the user is attempting to perform a complete IO
1256  *             operation.
1257  * @param[in]  io_request This parameter specifies the io request that is
1258  *             being completed.
1259  *
1260  * @return This method returns an indication that complete IO operations
1261  *         are not allowed.
1262  * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1263  */
1264 static
1265 SCI_STATUS scif_sas_domain_default_complete_high_priority_io_handler(
1266    SCI_BASE_DOMAIN_T        * domain,
1267    SCI_BASE_REMOTE_DEVICE_T * remote_device,
1268    SCI_BASE_REQUEST_T       * io_request,
1269    void                     * response_data,
1270    SCI_IO_STATUS              completion_status
1271 )
1272 {
1273    SCIF_LOG_WARNING((
1274       sci_base_object_get_logger(domain),
1275       SCIF_LOG_OBJECT_DOMAIN,
1276       "Domain:0x%x Device:0x%x State:0x%x complete IO message invalid\n",
1277       domain, remote_device,
1278       sci_base_state_machine_get_state(&domain->state_machine)
1279    ));
1280 
1281    return SCI_FAILURE_INVALID_STATE;
1282 }
1283 
1284 /**
1285  * @brief This method provides default handling (i.e. returns an error)
1286  *        when a user attempts to continue an IO on a domain and a
1287  *        continue IO operation is not allowed.
1288  *
1289  * @param[in]  domain This parameter specifies the domain object
1290  *             on which the user is attempting to perform a continue IO
1291  *             operation.
1292  * @param[in]  remote_device This parameter specifies the remote device
1293  *             object on which the user is attempting to perform a start IO
1294  *             operation.
1295  * @param[in]  io_request This parameter specifies the io request that is
1296  *             being started.
1297  *
1298  * @return This method returns an indication that continue IO operations
1299  *         are not allowed.
1300  * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1301  */
1302 static
1303 SCI_STATUS scif_sas_domain_default_continue_io_handler(
1304    SCI_BASE_DOMAIN_T        * domain,
1305    SCI_BASE_REMOTE_DEVICE_T * remote_device,
1306    SCI_BASE_REQUEST_T       * io_request
1307 )
1308 {
1309    SCIF_LOG_WARNING((
1310       sci_base_object_get_logger(domain),
1311       SCIF_LOG_OBJECT_DOMAIN,
1312       "Domain:0x%x Device:0x%x State:0x%x contineu IO message invalid\n",
1313       domain, remote_device,
1314       sci_base_state_machine_get_state(&domain->state_machine)
1315    ));
1316 
1317    return SCI_FAILURE_INVALID_STATE;
1318 }
1319 
1320 /**
1321  * @brief This method provides default handling (i.e. returns an error)
1322  *        when a user attempts to start a task on a domain and a start
1323  *        task operation is not allowed.
1324  *
1325  * @param[in]  domain This parameter specifies the domain object
1326  *             on which the user is attempting to perform a start task
1327  *             operation.
1328  * @param[in]  remote_device This parameter specifies the remote device
1329  *             object on which the user is attempting to perform a start IO
1330  *             operation.
1331  * @param[in]  task_request This parameter specifies the task request that
1332  *             is being started.
1333  *
1334  * @return This method returns an indication that start task operations
1335  *         are not allowed.
1336  * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1337  */
1338 static
1339 SCI_STATUS scif_sas_domain_default_start_task_handler(
1340    SCI_BASE_DOMAIN_T        * domain,
1341    SCI_BASE_REMOTE_DEVICE_T * remote_device,
1342    SCI_BASE_REQUEST_T       * task_request
1343 )
1344 {
1345    SCIF_LOG_WARNING((
1346       sci_base_object_get_logger(domain),
1347       SCIF_LOG_OBJECT_DOMAIN,
1348       "Domain:0x%x Device:0x%x State:0x%x start task message invalid\n",
1349       domain, remote_device,
1350       sci_base_state_machine_get_state(&domain->state_machine)
1351    ));
1352 
1353    return SCI_FAILURE_INVALID_STATE;
1354 }
1355 
1356 /**
1357  * @brief This method provides default handling (i.e. returns an error)
1358  *        when a user attempts to complete a task on a domain and a
1359  *        complete task operation is not allowed.
1360  *
1361  * @param[in]  domain This parameter specifies the domain object
1362  *             on which the user is attempting to perform a complete task
1363  *             operation.
1364  * @param[in]  remote_device This parameter specifies the remote device
1365  *             object on which the user is attempting to perform a start IO
1366  *             operation.
1367  * @param[in]  task_request This parameter specifies the task request that
1368  *             is being started.
1369  *
1370  * @return This method returns an indication that complete task operations
1371  *         are not allowed.
1372  * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1373  */
1374 static
1375 SCI_STATUS scif_sas_domain_default_complete_task_handler(
1376    SCI_BASE_DOMAIN_T        * domain,
1377    SCI_BASE_REMOTE_DEVICE_T * remote_device,
1378    SCI_BASE_REQUEST_T       * task_request
1379 )
1380 {
1381    SCIF_LOG_WARNING((
1382       sci_base_object_get_logger(domain),
1383       SCIF_LOG_OBJECT_DOMAIN,
1384       "Domain:0x%x Device:0x%x State:0x%x complete task message invalid\n",
1385       domain, remote_device,
1386       sci_base_state_machine_get_state(&domain->state_machine)
1387    ));
1388 
1389    return SCI_FAILURE_INVALID_STATE;
1390 }
1391 
1392 /**
1393  * @brief This method provides default handling (i.e. returns an error)
1394  *        when a remote device start operation completes in a state.
1395  *
1396  * @param[in]  domain This parameter specifies the domain object
1397  *             on which the remote device start operation is completing.
1398  * @param[in]  remote_device This parameter specifies the remote device
1399  *             for which the start operation is completing.
1400  *
1401  * @return This method returns an indication that start operation
1402  *         completion is not allowed.
1403  * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1404  */
1405 static
1406 SCI_STATUS scif_sas_domain_default_device_start_complete_handler(
1407    SCI_BASE_DOMAIN_T        * domain,
1408    SCI_BASE_REMOTE_DEVICE_T * remote_device
1409 )
1410 {
1411    SCIF_LOG_WARNING((
1412       sci_base_object_get_logger(domain),
1413       SCIF_LOG_OBJECT_DOMAIN,
1414       "Domain:0x%x Device:0x%x State:0x%x device stop complete message invalid\n",
1415       domain, remote_device,
1416       sci_base_state_machine_get_state(&domain->state_machine)
1417    ));
1418 
1419    return SCI_FAILURE_INVALID_STATE;
1420 }
1421 
1422 /**
1423  * @brief This method provides default handling (i.e. returns an error)
1424  *        when a remote device stop operation completes in a state.
1425  *
1426  * @param[in]  domain This parameter specifies the domain object
1427  *             on which the remote device stop operation is completing.
1428  * @param[in]  remote_device This parameter specifies the remote device
1429  *             for which the stop operation is completing.
1430  *
1431  * @return This method returns an indication that stop operation
1432  *         completion is not allowed.
1433  * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1434  */
1435 static
1436 SCI_STATUS scif_sas_domain_default_device_stop_complete_handler(
1437    SCI_BASE_DOMAIN_T        * domain,
1438    SCI_BASE_REMOTE_DEVICE_T * remote_device
1439 )
1440 {
1441    SCIF_LOG_WARNING((
1442       sci_base_object_get_logger(domain),
1443       SCIF_LOG_OBJECT_DOMAIN,
1444       "Domain:0x%x Device:0x%x State:0x%x device stop complete message invalid\n",
1445       domain, remote_device,
1446       sci_base_state_machine_get_state(&domain->state_machine)
1447    ));
1448 
1449    return SCI_FAILURE_INVALID_STATE;
1450 }
1451 
1452 /**
1453  * @brief This method provides default handling (i.e. returns an error)
1454  *        when sci user try to destruct a remote device of this domain.
1455  *
1456  * @param[in]  domain This parameter specifies the domain object
1457  *             on which the remote device is to be destructed.
1458  * @param[in]  remote_device This parameter specifies the remote device
1459  *             to be destructed.
1460  *
1461  * @return This method returns an indication that device destruction
1462  *         is not allowed.
1463  * @retval SCI_FAILURE_INVALID_STATE This value is always returned.
1464  */
1465 static
1466 SCI_STATUS scif_sas_domain_default_device_destruct_handler(
1467    SCI_BASE_DOMAIN_T        * domain,
1468    SCI_BASE_REMOTE_DEVICE_T * remote_device
1469 )
1470 {
1471    SCIF_LOG_WARNING((
1472       sci_base_object_get_logger(domain),
1473       SCIF_LOG_OBJECT_DOMAIN,
1474       "Domain:0x%x Device:0x%x State:0x%x device destruct in invalid state\n",
1475       domain, remote_device,
1476       sci_base_state_machine_get_state(&domain->state_machine)
1477    ));
1478 
1479    return SCI_FAILURE_INVALID_STATE;
1480 }
1481 
1482 
1483 /**
1484  * @brief This method provides handling when sci user destruct a remote
1485  *        device of this domain in discovering state. Mainly the device
1486  *        is removed from domain's remote_device_list.
1487  *
1488  * @param[in]  domain This parameter specifies the domain object
1489  *             on which the remote device is to be destructed.
1490  * @param[in]  remote_device This parameter specifies the remote device
1491  *             to be destructed.
1492  *
1493  * @return This method returns a status of the device destruction.
1494  * @retval SCI_SUCCESS This value is returned when a remote device is
1495  *         successfully removed from domain.
1496  */
1497 static
1498 SCI_STATUS scif_sas_domain_discovering_device_destruct_handler(
1499    SCI_BASE_DOMAIN_T        * domain,
1500    SCI_BASE_REMOTE_DEVICE_T * remote_device
1501 )
1502 {
1503    SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T *)domain;
1504 
1505    SCIF_LOG_WARNING((
1506       sci_base_object_get_logger(domain),
1507       SCIF_LOG_OBJECT_DOMAIN,
1508       "Domain:0x%x Device:0x%x State:0x%x device destruct in domain DISCOVERING state\n",
1509       domain, remote_device,
1510       sci_base_state_machine_get_state(&domain->state_machine)
1511    ));
1512 
1513    //remove the remote device from domain's remote_device_list
1514    sci_abstract_list_erase(
1515       &(fw_domain->remote_device_list),
1516       remote_device
1517    );
1518 
1519    return SCI_SUCCESS;
1520 }
1521 
1522 
1523 #define scif_sas_domain_stopped_discover_handler \
1524         scif_sas_domain_ready_discover_handler
1525 
1526 #define scif_sas_domain_default_start_high_priority_io_handler \
1527         scif_sas_domain_default_start_io_handler
1528 
1529 
1530 SCI_BASE_DOMAIN_STATE_HANDLER_T
1531    scif_sas_domain_state_handler_table[SCI_BASE_DOMAIN_MAX_STATES] =
1532 {
1533    // SCI_BASE_DOMAIN_STATE_INITIAL
1534    {
1535       scif_sas_domain_default_discover_handler,
1536       scif_sas_domain_default_port_ready_handler,
1537       scif_sas_domain_default_port_not_ready_handler,
1538       scif_sas_domain_default_device_start_complete_handler,
1539       scif_sas_domain_default_device_stop_complete_handler,
1540       scif_sas_domain_default_device_destruct_handler,
1541       scif_sas_domain_default_start_io_handler,
1542       scif_sas_domain_default_start_high_priority_io_handler,
1543       scif_sas_domain_default_complete_io_handler,
1544       scif_sas_domain_default_complete_high_priority_io_handler,
1545       scif_sas_domain_default_continue_io_handler,
1546       scif_sas_domain_default_start_task_handler,
1547       scif_sas_domain_default_complete_task_handler
1548    },
1549    // SCI_BASE_DOMAIN_STATE_STARTING
1550    {
1551       scif_sas_domain_default_discover_handler,
1552       scif_sas_domain_starting_port_ready_handler,
1553       scif_sas_domain_default_port_not_ready_handler,
1554       scif_sas_domain_default_device_start_complete_handler,
1555       scif_sas_domain_default_device_stop_complete_handler,
1556       scif_sas_domain_default_device_destruct_handler,
1557       scif_sas_domain_default_start_io_handler,
1558       scif_sas_domain_default_start_high_priority_io_handler,
1559       scif_sas_domain_default_complete_io_handler,
1560       scif_sas_domain_default_complete_high_priority_io_handler,
1561       scif_sas_domain_default_continue_io_handler,
1562       scif_sas_domain_default_start_task_handler,
1563       scif_sas_domain_default_complete_task_handler
1564    },
1565    // SCI_BASE_DOMAIN_STATE_READY
1566    {
1567       scif_sas_domain_ready_discover_handler,
1568       scif_sas_domain_default_port_ready_handler,
1569       scif_sas_domain_ready_port_not_ready_handler,
1570       scif_sas_domain_default_device_start_complete_handler,
1571       scif_sas_domain_default_device_stop_complete_handler,
1572       scif_sas_domain_default_device_destruct_handler,
1573       scif_sas_domain_ready_start_io_handler,
1574       scif_sas_domain_ready_start_high_priority_io_handler,
1575       scif_sas_domain_ready_complete_io_handler,
1576       scif_sas_domain_ready_complete_high_priority_io_handler,
1577       scif_sas_domain_ready_continue_io_handler,
1578       scif_sas_domain_ready_start_task_handler,
1579       scif_sas_domain_ready_complete_task_handler
1580    },
1581    // SCI_BASE_DOMAIN_STATE_STOPPING
1582    {
1583       scif_sas_domain_default_discover_handler,
1584       scif_sas_domain_default_port_ready_handler,
1585       scif_sas_domain_default_port_not_ready_handler,
1586       scif_sas_domain_default_device_start_complete_handler,
1587       scif_sas_domain_stopping_device_stop_complete_handler,
1588       scif_sas_domain_default_device_destruct_handler,
1589       scif_sas_domain_default_start_io_handler,
1590       scif_sas_domain_default_start_high_priority_io_handler,
1591       scif_sas_domain_stopping_complete_io_handler,
1592       scif_sas_domain_stopping_complete_high_priority_io_handler,
1593       scif_sas_domain_default_continue_io_handler,
1594       scif_sas_domain_default_start_task_handler,
1595       scif_sas_domain_stopping_complete_task_handler
1596    },
1597    // SCI_BASE_DOMAIN_STATE_STOPPED
1598    {
1599       scif_sas_domain_stopped_discover_handler,
1600       scif_sas_domain_default_port_ready_handler,
1601       scif_sas_domain_default_port_not_ready_handler,
1602       scif_sas_domain_default_device_start_complete_handler,
1603       scif_sas_domain_default_device_stop_complete_handler,
1604       scif_sas_domain_default_device_destruct_handler,
1605       scif_sas_domain_default_start_io_handler,
1606       scif_sas_domain_default_start_high_priority_io_handler,
1607       scif_sas_domain_default_complete_io_handler,
1608       scif_sas_domain_default_complete_high_priority_io_handler,
1609       scif_sas_domain_default_continue_io_handler,
1610       scif_sas_domain_default_start_task_handler,
1611       scif_sas_domain_default_complete_task_handler
1612    },
1613    // SCI_BASE_DOMAIN_STATE_DISCOVERING
1614    {
1615       scif_sas_domain_default_discover_handler,
1616       scif_sas_domain_default_port_ready_handler,
1617       scif_sas_domain_discovering_port_not_ready_handler,
1618       scif_sas_domain_discovering_device_start_complete_handler,
1619       scif_sas_domain_discovering_device_stop_complete_handler,
1620       scif_sas_domain_discovering_device_destruct_handler,  //
1621       scif_sas_domain_default_start_io_handler,
1622       scif_sas_domain_discovering_start_high_priority_io_handler,
1623       scif_sas_domain_discovering_complete_io_handler,
1624       scif_sas_domain_discovering_complete_high_priority_io_handler, //
1625       scif_sas_domain_discovering_continue_io_handler,
1626       scif_sas_domain_discovering_start_task_handler,
1627       scif_sas_domain_discovering_complete_task_handler
1628    }
1629 };
1630 
1631