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