2 * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
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.
9 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
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.
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.
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.
28 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
29 * All rights reserved.
31 * Redistribution and use in source and binary forms, with or without
32 * modification, are permitted provided that the following conditions
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
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.
55 #include <sys/cdefs.h>
56 __FBSDID("$FreeBSD$");
61 * @brief This file contains the implementation of the SCIF_SAS_DOMAIN
65 #include <dev/isci/scil/intel_sas.h>
66 #include <dev/isci/scil/sci_fast_list.h>
67 #include <dev/isci/scil/scic_controller.h>
68 #include <dev/isci/scil/scic_port.h>
69 #include <dev/isci/scil/scic_remote_device.h>
70 #include <dev/isci/scil/scic_io_request.h>
71 #include <dev/isci/scil/scic_user_callback.h>
72 #include <dev/isci/scil/scif_user_callback.h>
73 #include <dev/isci/scil/sci_abstract_list.h>
74 #include <dev/isci/scil/sci_base_iterator.h>
76 #include <dev/isci/scil/scif_sas_logger.h>
77 #include <dev/isci/scil/scif_sas_domain.h>
78 #include <dev/isci/scil/scif_sas_controller.h>
79 #include <dev/isci/scil/scif_sas_remote_device.h>
80 #include <dev/isci/scil/scif_sas_smp_remote_device.h>
81 #include <dev/isci/scil/sci_util.h>
83 //******************************************************************************
84 //* P R I V A T E M E T H O D S
85 //******************************************************************************
88 * @brief This method will attempt to handle an operation timeout (i.e.
89 * discovery or reset).
91 * @param[in] cookie This parameter specifies the domain in which the
97 void scif_sas_domain_operation_timeout_handler(
101 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*) cookie;
104 state = sci_base_state_machine_get_state(&fw_domain->parent.state_machine);
106 // Based upon the state of the domain, we know whether we were in the
107 // process of performing discovery or a reset.
108 if (state == SCI_BASE_DOMAIN_STATE_DISCOVERING)
111 sci_base_object_get_logger(fw_domain),
112 SCIF_LOG_OBJECT_DOMAIN,
113 "Domain:0x%x State:0x%x DISCOVER timeout!\n",
117 fw_domain->operation.status = SCI_FAILURE_TIMEOUT;
119 //search all the smp devices in the domain and cancel their activities
120 //if there is any outstanding activity remained. The smp devices will terminate
121 //all the started internal IOs.
122 scif_sas_domain_cancel_smp_activities(fw_domain);
124 scif_sas_domain_continue_discover(fw_domain);
129 sci_base_object_get_logger(fw_domain),
130 SCIF_LOG_OBJECT_DOMAIN,
131 "Domain:0x%x State:0x%x operation timeout in invalid state\n",
137 //******************************************************************************
138 //* P U B L I C M E T H O D S
139 //******************************************************************************
141 SCI_PORT_HANDLE_T scif_domain_get_scic_port_handle(
142 SCI_DOMAIN_HANDLE_T domain
145 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*) domain;
147 if ( (fw_domain == NULL) || (fw_domain->core_object == SCI_INVALID_HANDLE) )
148 return SCI_INVALID_HANDLE;
151 sci_base_object_get_logger(fw_domain),
152 SCIF_LOG_OBJECT_DOMAIN,
153 "Domain:0x%x no associated core port found\n",
157 return fw_domain->core_object;
160 // ---------------------------------------------------------------------------
162 SCI_REMOTE_DEVICE_HANDLE_T scif_domain_get_device_by_sas_address(
163 SCI_DOMAIN_HANDLE_T domain,
164 SCI_SAS_ADDRESS_T * sas_address
167 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*) domain;
168 SCI_ABSTRACT_ELEMENT_T * element = sci_abstract_list_get_front(
169 &fw_domain->remote_device_list
171 SCIF_SAS_REMOTE_DEVICE_T * fw_device;
172 SCI_SAS_ADDRESS_T fw_device_address;
175 sci_base_object_get_logger(domain),
176 SCIF_LOG_OBJECT_DOMAIN,
177 "scif_domain_get_device_by_sas_address(0x%x, 0x%x) enter\n",
181 // Search the abstract list to see if there is a remote device with the
183 while (element != NULL)
185 fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
186 sci_abstract_list_get_object(element);
188 scic_remote_device_get_sas_address(
189 fw_device->core_object, &fw_device_address
192 // Check to see if this is the device for which we are searching.
193 if ( (fw_device_address.low == sas_address->low)
194 && (fw_device_address.high == sas_address->high) )
199 element = sci_abstract_list_get_next(element);
202 return SCI_INVALID_HANDLE;
205 // ---------------------------------------------------------------------------
207 #if !defined(DISABLE_SCI_ITERATORS)
209 SCI_ITERATOR_HANDLE_T scif_domain_get_remote_device_iterator(
210 SCI_DOMAIN_HANDLE_T domain,
211 void * iterator_buffer
214 SCI_ITERATOR_HANDLE_T iterator = (SCI_ITERATOR_HANDLE_T *)iterator_buffer;
216 sci_base_iterator_construct(
217 iterator, &((SCIF_SAS_DOMAIN_T*) domain)->remote_device_list
224 #endif // !defined(DISABLE_SCI_ITERATORS)
226 // ---------------------------------------------------------------------------
228 SCI_STATUS scif_domain_discover(
229 SCI_DOMAIN_HANDLE_T domain,
230 U32 discover_timeout,
234 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*) domain;
235 SCI_STATUS status = SCI_SUCCESS;
236 SCI_STATUS op_status = SCI_SUCCESS;
239 sci_base_object_get_logger(domain),
240 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
241 "scif_domain_discover(0x%x, 0x%x, 0x%x) enter\n",
242 domain, discover_timeout, device_timeout
245 // Check to make sure the size of the domain doesn't cause potential issues
246 // with the remote device timer and the domain timer.
247 if ((device_timeout * sci_abstract_list_size(&fw_domain->remote_device_list))
249 status = SCI_WARNING_TIMER_CONFLICT;
251 op_status = fw_domain->state_handlers->discover_handler(
252 &fw_domain->parent, discover_timeout, device_timeout
255 // The status of the discover operation takes priority.
256 if ( (status == SCI_SUCCESS)
257 || (status != SCI_SUCCESS && op_status != SCI_SUCCESS) )
265 // ---------------------------------------------------------------------------
267 U32 scif_domain_get_suggested_discover_timeout(
268 SCI_DOMAIN_HANDLE_T domain
271 U32 suggested_timeout = SCIF_DOMAIN_DISCOVER_TIMEOUT; //milli-seconds
272 return suggested_timeout;
275 // ---------------------------------------------------------------------------
277 void scic_cb_port_stop_complete(
278 SCI_CONTROLLER_HANDLE_T controller,
279 SCI_PORT_HANDLE_T port,
280 SCI_STATUS completion_status
284 sci_base_object_get_logger((SCIF_SAS_DOMAIN_T*)sci_object_get_association(port)),
285 SCIF_LOG_OBJECT_DOMAIN,
286 "scic_cb_port_stop_complete(0x%x, 0x%x, 0x%x) enter\n",
287 controller, port, completion_status
291 // ---------------------------------------------------------------------------
293 void scic_cb_port_ready(
294 SCI_CONTROLLER_HANDLE_T controller,
295 SCI_PORT_HANDLE_T port
298 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*)
299 sci_object_get_association(port);
302 sci_base_object_get_logger(fw_domain),
303 SCIF_LOG_OBJECT_DOMAIN,
304 "scic_cb_port_ready(0x%x, 0x%x) enter\n",
308 // The controller supplied with the port should match the controller
309 // saved in the domain.
310 ASSERT(sci_object_get_association(controller) == fw_domain->controller);
312 fw_domain->is_port_ready = TRUE;
314 fw_domain->state_handlers->port_ready_handler(&fw_domain->parent);
317 // ---------------------------------------------------------------------------
319 void scic_cb_port_not_ready(
320 SCI_CONTROLLER_HANDLE_T controller,
321 SCI_PORT_HANDLE_T port,
325 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*)
326 sci_object_get_association(port);
329 sci_base_object_get_logger(fw_domain),
330 SCIF_LOG_OBJECT_DOMAIN,
331 "scic_cb_port_not_ready(0x%x, 0x%x) enter\n",
335 // The controller supplied with the port should match the controller
336 // saved in the domain.
337 ASSERT(sci_object_get_association(controller) == fw_domain->controller);
339 // There is no need to take action on the port reconfiguring since it is
340 // just a change of the port width.
341 if (reason_code != SCIC_PORT_NOT_READY_RECONFIGURING)
343 fw_domain->is_port_ready = FALSE;
345 fw_domain->state_handlers->port_not_ready_handler(
346 &fw_domain->parent, reason_code);
350 // ---------------------------------------------------------------------------
352 void scic_cb_port_hard_reset_complete(
353 SCI_CONTROLLER_HANDLE_T controller,
354 SCI_PORT_HANDLE_T port,
355 SCI_STATUS completion_status
358 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*)
359 sci_object_get_association(port);
360 SCIF_SAS_REMOTE_DEVICE_T * fw_device;
361 SCI_FAST_LIST_ELEMENT_T * element = fw_domain->request_list.list_head;
362 SCIF_SAS_TASK_REQUEST_T * task_request = NULL;
365 sci_base_object_get_logger(fw_domain),
366 SCIF_LOG_OBJECT_DOMAIN,
367 "scic_cb_port_hard_reset_complete(0x%x, 0x%x, 0x%x) enter\n",
368 controller, port, completion_status
371 while (element != NULL)
373 task_request = (SCIF_SAS_TASK_REQUEST_T*) sci_fast_list_get_object(element);
374 element = sci_fast_list_get_next(element);
376 if (scif_sas_task_request_get_function(task_request)
377 == SCI_SAS_HARD_RESET)
379 fw_device = task_request->parent.device;
381 if (fw_device->domain == fw_domain)
383 scic_remote_device_reset_complete(fw_device->core_object);
385 scif_cb_task_request_complete(
386 sci_object_get_association(controller),
389 (SCI_TASK_STATUS) completion_status
398 // ---------------------------------------------------------------------------
400 void scic_cb_port_bc_change_primitive_recieved(
401 SCI_CONTROLLER_HANDLE_T controller,
402 SCI_PORT_HANDLE_T port,
406 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*)
407 sci_object_get_association(port);
409 SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)
410 sci_object_get_association(controller);
413 sci_base_object_get_logger(fw_domain),
414 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
415 "scic_cb_port_bc_change_primitive_recieved(0x%x, 0x%x, 0x%x) enter\n",
416 controller, port, phy
419 if (fw_domain->broadcast_change_count == 0)
420 { // Enable the BCN detection only if the bcn_count is zero. If bcn_count is
421 // not zero at this time, we won't enable BCN detection since all non-zero
422 // BCN_count means same to us. Furthermore, we avoid BCN storm by not
423 // always enabling the BCN_detection.
424 scic_port_enable_broadcast_change_notification(fw_domain->core_object);
427 fw_domain->broadcast_change_count++;
429 //if there is smp device on this domain that is in the middle of discover
430 //process or smp target reset, don't notify the driver layer.
431 if( ! scif_sas_domain_is_in_smp_activity(fw_domain) )
432 // Notify the user that there is, potentially, a change to the domain.
433 scif_cb_domain_change_notification(fw_controller, fw_domain);
436 // ---------------------------------------------------------------------------
438 void scic_cb_port_bc_ses_primitive_recieved(
439 SCI_CONTROLLER_HANDLE_T controller,
440 SCI_PORT_HANDLE_T port,
445 sci_base_object_get_logger(sci_object_get_association(port)),
446 SCIF_LOG_OBJECT_DOMAIN,
447 "scic_cb_port_bc_ses_primitive_received(0x%x, 0x%x, 0x%x) enter\n",
448 controller, port, phy
452 // ---------------------------------------------------------------------------
454 void scic_cb_port_bc_expander_primitive_recieved(
455 SCI_CONTROLLER_HANDLE_T controller,
456 SCI_PORT_HANDLE_T port,
461 sci_base_object_get_logger(sci_object_get_association(port)),
462 SCIF_LOG_OBJECT_DOMAIN,
463 "scic_cb_port_bc_expander_primitive_received(0x%x, 0x%x, 0x%x) enter\n",
464 controller, port, phy
468 // ---------------------------------------------------------------------------
470 void scic_cb_port_bc_aen_primitive_recieved(
471 SCI_CONTROLLER_HANDLE_T controller,
472 SCI_PORT_HANDLE_T port,
477 sci_base_object_get_logger(sci_object_get_association(port)),
478 SCIF_LOG_OBJECT_DOMAIN,
479 "scic_cb_port_bc_aen_primitive_received(0x%x, 0x%x, 0x%x) enter\n",
480 controller, port, phy
484 // ---------------------------------------------------------------------------
486 void scic_cb_port_link_up(
487 SCI_CONTROLLER_HANDLE_T controller,
488 SCI_PORT_HANDLE_T port,
492 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*)
493 sci_object_get_association(port);
496 sci_base_object_get_logger(sci_object_get_association(port)),
497 SCIF_LOG_OBJECT_DOMAIN,
498 "scic_cb_port_link_up(0x%x, 0x%x, 0x%x) enter\n",
499 controller, port, phy
502 scif_sas_domain_update_device_port_width(fw_domain, port);
505 // ---------------------------------------------------------------------------
507 void scic_cb_port_link_down(
508 SCI_CONTROLLER_HANDLE_T controller,
509 SCI_PORT_HANDLE_T port,
513 SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*)
514 sci_object_get_association(port);
517 sci_base_object_get_logger(sci_object_get_association(port)),
518 SCIF_LOG_OBJECT_DOMAIN,
519 "scic_cb_port_link_down(0x%x, 0x%x, 0x%x) enter\n",
520 controller, port, phy
523 scif_sas_domain_update_device_port_width(fw_domain, port);
526 //******************************************************************************
527 //* P R O T E C T E D M E T H O D S
528 //******************************************************************************
531 * @brief This method constructs the framework's SAS domain object. During
532 * the construction process a linkage to the corresponding core port
535 * @param[in] domain This parameter specifies the domain object to be
537 * @param[in] domain_id This parameter specifies the ID for the domain
539 * @param[in] fw_controller This parameter specifies the controller managing
540 * the domain being constructed.
544 void scif_sas_domain_construct(
545 SCIF_SAS_DOMAIN_T * fw_domain,
547 SCIF_SAS_CONTROLLER_T * fw_controller
551 sci_base_object_get_logger(fw_controller),
552 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_INITIALIZATION,
553 "scif_sas_domain_construct(0x%x, 0x%x, 0x%x) enter\n",
554 fw_domain, domain_id, fw_controller
557 sci_base_domain_construct(
559 sci_base_object_get_logger(fw_controller),
560 scif_sas_domain_state_table
563 scif_sas_domain_initialize_state_logging(fw_domain);
565 sci_abstract_list_construct(
566 &fw_domain->remote_device_list, &fw_controller->free_remote_device_pool
569 // Retrieve the core's port object that directly corresponds to this
571 scic_controller_get_port_handle(
572 fw_controller->core_object, domain_id, &fw_domain->core_object
575 // Set the association in the core port to this framework domain object.
576 sci_object_set_association(
577 (SCI_OBJECT_HANDLE_T) fw_domain->core_object, fw_domain
580 sci_fast_list_init(&fw_domain->request_list);
582 fw_domain->operation.timer = NULL;
584 fw_domain->is_port_ready = FALSE;
585 fw_domain->device_start_count = 0;
586 fw_domain->controller = fw_controller;
587 fw_domain->operation.status = SCI_SUCCESS;
588 fw_domain->is_config_route_table_needed = FALSE;
592 * @brief This method will terminate the requests outstanding in the core
593 * based on the supplied criteria.
594 * - if the all three parameters are specified then only the single
595 * SCIF_SAS_REQUEST object is terminated.
596 * - if only the SCIF_SAS_DOMAIN and SCIF_SAS_REMOTE_DEVICE are
597 * specified, then all SCIF_SAS_REQUEST objects outstanding at
598 * the device are terminated. The one exclusion to this rule is
599 * that the fw_requestor is not terminated.
600 * - if only the SCIF_SAS_DOMAIN object is specified, then all
601 * SCIF_SAS_REQUEST objects outstanding in the domain are
604 * @param[in] fw_domain This parameter specifies the domain in which to
605 * terminate requests.
606 * @param[in] fw_device This parameter specifies the remote device in
607 * which to terminate requests. This parameter can be NULL
608 * as long as the fw_request parameter is NULL. It is a
609 * required parameter if the fw_request parameter is not NULL.
610 * @param[in] fw_request This parameter specifies the request object to
611 * be terminated. This parameter can be NULL.
612 * @param[in] fw_requestor This parameter specifies the task management
613 * request that is responsible for the termination of requests.
617 void scif_sas_domain_terminate_requests(
618 SCIF_SAS_DOMAIN_T * fw_domain,
619 SCIF_SAS_REMOTE_DEVICE_T * fw_device,
620 SCIF_SAS_REQUEST_T * fw_request,
621 SCIF_SAS_TASK_REQUEST_T * fw_requestor
625 sci_base_object_get_logger(fw_domain),
626 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
627 "scif_sas_domain_terminate_requests(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
628 fw_domain, fw_device, fw_request, fw_requestor
631 if (fw_request != NULL)
633 fw_request->terminate_requestor = fw_requestor;
634 fw_request->state_handlers->abort_handler(&fw_request->parent);
638 SCI_FAST_LIST_ELEMENT_T * element = fw_domain->request_list.list_head;
639 SCIF_SAS_REQUEST_T * request = NULL;
641 // Cycle through the fast list of IO requests. Terminate each
642 // outstanding requests that matches the criteria supplied by the
644 while (element != NULL)
646 request = (SCIF_SAS_REQUEST_T*) sci_fast_list_get_object(element);
647 // The current element may be deleted from the list because of
648 // IO completion so advance to the next element early
649 element = sci_fast_list_get_next(element);
651 // Ensure we pass the supplied criteria before terminating the
656 (request->device == fw_device)
657 && (fw_requestor != (SCIF_SAS_TASK_REQUEST_T*) request)
662 (request->is_waiting_for_abort_task_set == FALSE) ||
663 (request->terminate_requestor == NULL)
666 request->terminate_requestor = fw_requestor;
667 request->state_handlers->abort_handler(&request->parent);
675 * @brief This method searches the domain object to find a
676 * SCIF_SAS_REQUEST object associated with the supplied IO tag.
678 * @param[in] fw_domain This parameter specifies the domain in which to
679 * to find the request object.
680 * @param[in] io_tag This parameter specifies the IO tag value for which
681 * to locate the corresponding request.
683 * @return This method returns a pointer to the SCIF_SAS_REQUEST object
684 * associated with the supplied IO tag.
685 * @retval NULL This value is returned if the IO tag does not resolve to
688 SCIF_SAS_REQUEST_T * scif_sas_domain_get_request_by_io_tag(
689 SCIF_SAS_DOMAIN_T * fw_domain,
693 SCI_FAST_LIST_ELEMENT_T * element = fw_domain->request_list.list_head;
694 SCIF_SAS_IO_REQUEST_T * io_request = NULL;
697 sci_base_object_get_logger(fw_domain),
698 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
699 "scif_sas_domain_get_request_by_io_tag(0x%x, 0x%x) enter\n",
703 while (element != NULL)
705 io_request = (SCIF_SAS_IO_REQUEST_T*) sci_fast_list_get_object(element);
707 // Check to see if we located the request with an identical IO tag.
708 if (scic_io_request_get_io_tag(io_request->parent.core_object) == io_tag)
709 return &io_request->parent;
711 element = sci_fast_list_get_next(element);
718 * @brief This method performs domain object initialization to be done
719 * when the scif_controller_initialize() method is invoked.
720 * This includes operation timeout creation.
722 * @param[in] fw_domain This parameter specifies the domain object for
723 * which to perform initialization.
727 void scif_sas_domain_initialize(
728 SCIF_SAS_DOMAIN_T * fw_domain
732 sci_base_object_get_logger(fw_domain),
733 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_INITIALIZATION,
734 "scif_sas_domain_initialize(0x%x) enter\n",
738 // Create the timer for each domain. It is too early in the process
739 // to allocate this during construction since the user didn't have
740 // a chance to set it's association.
741 if (fw_domain->operation.timer == 0)
743 fw_domain->operation.timer = scif_cb_timer_create(
744 fw_domain->controller,
745 scif_sas_domain_operation_timeout_handler,
752 * @brief This method performs domain object handling for core remote
753 * device start complete notifications. Core remote device starts
754 * and start completes are only done during discovery. This could
755 * ultimately be wrapped into a handler method on the domain (they
756 * actually already exist). This method will decrement the number
757 * of device start operations ongoing and attempt to determine if
758 * discovery is complete.
760 * @param[in] fw_domain This parameter specifies the domain object for
761 * which to perform initialization.
765 void scif_sas_domain_remote_device_start_complete(
766 SCIF_SAS_DOMAIN_T * fw_domain,
767 SCIF_SAS_REMOTE_DEVICE_T * fw_device
770 SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols;
773 sci_base_object_get_logger(fw_domain),
774 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
775 "scif_sas_domain_remote_device_start_complete(0x%x, 0x%x) enter\n",
779 // If a device is being started/start completed, then we must be
781 ASSERT(fw_domain->parent.state_machine.current_state_id
782 == SCI_BASE_DOMAIN_STATE_DISCOVERING);
784 scic_remote_device_get_protocols(fw_device->core_object, &dev_protocols);
786 // Decrement the number of devices being started and check to see
787 // if all have finished being started or failed as the case may be.
788 fw_domain->device_start_in_progress_count--;
790 if ( dev_protocols.u.bits.attached_smp_target )
792 if ( fw_device->containing_device == NULL )
793 //kick off the smp discover process if this expander is direct attached.
794 scif_sas_smp_remote_device_start_discover(fw_device);
796 //mark this device, the discover process of this device will start after
797 //its containing smp device finish discover.
798 fw_device->protocol_device.smp_device.scheduled_activity =
799 SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_DISCOVER;
803 fw_domain->state_handlers->device_start_complete_handler(
804 &fw_domain->parent, &fw_device->parent
811 * @brief This methods check each smp device in this domain. If there is at
812 * least one smp device in discover or target reset activity, this
813 * domain is considered in smp activity. Note this routine is not
814 * called on fast IO path.
816 * @param[in] fw_domain The framework domain object
818 * @return BOOL value to indicate whether a domain is in SMP activity.
820 BOOL scif_sas_domain_is_in_smp_activity(
821 SCIF_SAS_DOMAIN_T * fw_domain
824 SCI_ABSTRACT_ELEMENT_T * current_element =
825 sci_abstract_list_get_front(&fw_domain->remote_device_list);
827 SCIF_SAS_REMOTE_DEVICE_T * current_device;
829 while ( current_element != NULL )
831 SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols;
833 current_device = (SCIF_SAS_REMOTE_DEVICE_T *)
834 sci_abstract_list_get_object(current_element);
836 scic_remote_device_get_protocols(current_device->core_object,
840 if (dev_protocols.u.bits.attached_smp_target &&
841 scif_sas_smp_remote_device_is_in_activity(current_device))
845 sci_abstract_list_get_next(current_element);
853 * @brief This methods finds a expander attached device by searching the domain's
854 * device list using connected expander device and expander phy id.
856 * @param[in] fw_domain The framework domain object
857 * @param[in] parent_device The expander device the target device attaches to.
858 * @param[in] expander_phy_id The expander phy id that the target device owns.
860 * @return found remote device or a NULL value if no device found.
862 SCIF_SAS_REMOTE_DEVICE_T * scif_sas_domain_get_device_by_containing_device(
863 SCIF_SAS_DOMAIN_T * fw_domain,
864 SCIF_SAS_REMOTE_DEVICE_T * containing_device,
868 SCIF_SAS_REMOTE_DEVICE_T * fw_device;
869 SCI_ABSTRACT_ELEMENT_T * element = sci_abstract_list_get_front(
870 &fw_domain->remote_device_list
873 //parent device must not be NULL.
874 ASSERT(containing_device != NULL);
876 // Search the abstract list to see if there is a remote device meets the
878 while (element != NULL)
880 fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
881 sci_abstract_list_get_object(element);
883 // Check to see if this is the device for which we are searching.
885 (fw_device->containing_device == containing_device)
886 && (fw_device->expander_phy_identifier == expander_phy_id)
892 element = sci_abstract_list_get_next(element);
895 return SCI_INVALID_HANDLE;
900 * @brief This methods finds the first device that is in STOPPED state and its
901 * connection_rate is still in SPINUP_HOLD(value 3).
903 * @param[in] fw_domain The framework domain object
905 * @return SCIF_SAS_REMOTE_DEVICE_T The device that is in SPINUP_HOLD or NULL.
907 SCIF_SAS_REMOTE_DEVICE_T * scif_sas_domain_find_device_in_spinup_hold(
908 SCIF_SAS_DOMAIN_T * fw_domain
911 SCI_ABSTRACT_ELEMENT_T * current_element;
912 SCIF_SAS_REMOTE_DEVICE_T * current_device;
915 sci_base_object_get_logger(fw_domain),
916 SCIF_LOG_OBJECT_DOMAIN,
917 "scif_sas_domain_find_device_in_spinup_hold(0x%x) enter\n",
921 //search throught domain's device list to find the first sata device on spinup_hold
922 current_element = sci_abstract_list_get_front(&fw_domain->remote_device_list);
923 while (current_element != NULL )
925 current_device = (SCIF_SAS_REMOTE_DEVICE_T *)
926 sci_abstract_list_get_object(current_element);
928 //We must get the next element before we remove the current
929 //device. Or else, we will get wrong next_element, since the erased
930 //element has been put into free pool.
931 current_element = sci_abstract_list_get_next(current_element);
933 if ( sci_base_state_machine_get_state(¤t_device->parent.state_machine) ==
934 SCI_BASE_REMOTE_DEVICE_STATE_STOPPED
935 && scic_remote_device_get_connection_rate(current_device->core_object) ==
936 SCI_SATA_SPINUP_HOLD )
938 return current_device;
947 * @brief This methods finds the first device that has specific activity scheduled.
949 * @param[in] fw_domain The framework domain object
950 * @param[in] smp_activity A specified smp activity. The valid range is [1,5].
952 * @return SCIF_SAS_REMOTE_DEVICE_T The device that has specified smp activity scheduled.
954 SCIF_SAS_REMOTE_DEVICE_T * scif_sas_domain_find_device_has_scheduled_activity(
955 SCIF_SAS_DOMAIN_T * fw_domain,
959 SCI_ABSTRACT_ELEMENT_T * current_element =
960 sci_abstract_list_get_front(&fw_domain->remote_device_list);
962 SCIF_SAS_REMOTE_DEVICE_T * current_device;
963 SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols;
965 //config route table activity has higher priority than discover activity.
966 while ( current_element != NULL )
968 current_device = (SCIF_SAS_REMOTE_DEVICE_T *)
969 sci_abstract_list_get_object(current_element);
971 scic_remote_device_get_protocols(current_device->core_object,
975 sci_abstract_list_get_next(current_element);
977 if ( dev_protocols.u.bits.attached_smp_target
978 && current_device->protocol_device.smp_device.scheduled_activity ==
981 return current_device;
990 * @brief This methods finds the smp device that has is_config_route_table_scheduled
991 * flag set to TRUE, and start config route table on it. If there is no
992 * smp device scheduled to config route table, find the smp device has
993 * is_discover_scheduled and start the smp discover process on them.
995 * @param[in] fw_domain The framework domain that to start smp discover process.
999 void scif_sas_domain_start_smp_activity(
1000 SCIF_SAS_DOMAIN_T * fw_domain
1003 SCIF_SAS_REMOTE_DEVICE_T * device_has_scheduled_activity = NULL;
1005 //first, find device that has config route table activity scheduled.
1006 //config route table activity has higher priority than Discover.
1007 device_has_scheduled_activity =
1008 scif_sas_domain_find_device_has_scheduled_activity(
1010 SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_CONFIG_ROUTE_TABLE
1013 if (device_has_scheduled_activity != NULL)
1015 scif_sas_smp_remote_device_configure_route_table(device_has_scheduled_activity);
1016 device_has_scheduled_activity->protocol_device.smp_device.scheduled_activity =
1017 SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_NONE;
1021 //if no device has config route table activity scheduled, search again, find
1022 //device has discover activity scheduled.
1023 device_has_scheduled_activity =
1024 scif_sas_domain_find_device_has_scheduled_activity(
1026 SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_DISCOVER
1029 if (device_has_scheduled_activity != NULL)
1030 scif_sas_smp_remote_device_start_discover(device_has_scheduled_activity);
1035 * @brief This method starts domain's smp discover process from the top level expander.
1037 * @param[in] fw_domain The framework domain that to start smp discover process.
1038 @ @param[in] top_expander The top level expander device to start smp discover process.
1042 void scif_sas_domain_start_smp_discover(
1043 SCIF_SAS_DOMAIN_T * fw_domain,
1044 SCIF_SAS_REMOTE_DEVICE_T * top_expander
1047 SCI_ABSTRACT_ELEMENT_T * current_element =
1048 sci_abstract_list_get_front(&fw_domain->remote_device_list);
1050 SCIF_SAS_REMOTE_DEVICE_T * current_device;
1052 // something changed behind expander
1053 // mark all the device behind expander to be NOT
1054 // is_currently_discovered.
1055 while ( current_element != NULL )
1057 current_device = (SCIF_SAS_REMOTE_DEVICE_T *)
1058 sci_abstract_list_get_object(current_element);
1060 current_device->is_currently_discovered = FALSE;
1062 //reset all the devices' port witdh except the top expander.
1063 if (current_device->containing_device != NULL)
1064 current_device->device_port_width = 1;
1066 current_element = sci_abstract_list_get_next(current_element);
1069 //expander device itself should be set to is_currently_discovered.
1070 top_expander->is_currently_discovered = TRUE;
1072 //kick off the smp discover process.
1073 scif_sas_smp_remote_device_start_discover(top_expander);
1078 * @brief This method continues domain's smp discover process and
1079 * may transit to READY state if all smp activities are done.
1081 * @param[in] fw_domain The framework domain that to start smp discover process.
1085 void scif_sas_domain_continue_discover(
1086 SCIF_SAS_DOMAIN_T * fw_domain
1090 sci_base_object_get_logger(fw_domain),
1091 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
1092 "scif_sas_domain_continue_discover(0x%x) enter\n",
1096 if ( fw_domain->device_start_in_progress_count == 0
1097 && !scif_sas_domain_is_in_smp_activity(fw_domain) )
1099 //domain scrub the remote device list to see if there is a need
1100 //to start smp discover on expander device. There may be no
1101 //need to start any smp discover.
1102 scif_sas_domain_start_smp_activity(fw_domain);
1104 //In domain discovery timeout case, we cancel all
1105 //the smp activities, and terminate all the smp requests, then
1106 //this routine is called. But the smp request may not done
1107 //terminated. We want to guard the domain trasitting to READY
1108 //by checking outstanding smp request count. If there is outstanding
1109 //smp request, the domain will not transit to READY. Later when
1110 //the smp request is terminated at smp remote device, this routine
1111 //will be called then the domain will transit to READY state.
1112 if ( ! scif_sas_domain_is_in_smp_activity(fw_domain)
1113 && scif_sas_domain_get_smp_request_count(fw_domain) == 0)
1115 //before domain transit to READY state, domain has some clean up
1116 //work to do, such like update domain's remote devcie list.
1117 scif_sas_domain_finish_discover(fw_domain);
1124 * @brief This method finishes domain's smp discover process and
1125 * update domain's remote device list.
1127 * @param[in] fw_domain The framework domain that's to finish smp discover process.
1131 void scif_sas_domain_finish_discover(
1132 SCIF_SAS_DOMAIN_T * fw_domain
1135 SCIF_SAS_REMOTE_DEVICE_T * current_device = NULL;
1136 SCI_ABSTRACT_ELEMENT_T * current_element = NULL;
1139 sci_base_object_get_logger(fw_domain),
1140 SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
1141 "scif_sas_domain_finish_discover(0x%x) enter\n",
1145 //need to scrub all the devices behind the expander. Check each
1146 //device's discover_status. if the is_currently_discovered is FALSE, means
1147 //the device is not been rediscovered. this device needs to be removed.
1148 current_element = sci_abstract_list_get_front(&fw_domain->remote_device_list);
1149 while (current_element != NULL )
1151 current_device = (SCIF_SAS_REMOTE_DEVICE_T *)
1152 sci_abstract_list_get_object(current_element);
1154 //We must get the next element before we remove the current
1155 //device. Or else, we will get wrong next_element, since the erased
1156 //element has been put into free pool.
1157 current_element = sci_abstract_list_get_next(current_element);
1159 if ( current_device->is_currently_discovered == FALSE )
1161 // Notify the framework user of the device removal.
1162 scif_cb_domain_device_removed(
1163 fw_domain->controller, fw_domain, current_device
1168 sci_base_state_machine_change_state(
1169 &fw_domain->parent.state_machine, SCI_BASE_DOMAIN_STATE_READY
1176 * @brief This method remove an expander device and its child devices, in order to
1177 * deal with a detected illeagal phy connection.
1179 * @param[in] fw_domain The domain that a expander belongs to.
1180 * @param[in] fw_device The expander device to be removed.
1184 void scif_sas_domain_remove_expander_device(
1185 SCIF_SAS_DOMAIN_T * fw_domain,
1186 SCIF_SAS_REMOTE_DEVICE_T * fw_device
1189 SCIF_SAS_SMP_REMOTE_DEVICE_T * smp_remote_device =
1190 &fw_device->protocol_device.smp_device;
1192 SCI_FAST_LIST_ELEMENT_T * element = smp_remote_device->smp_phy_list.list_head;
1193 SCIF_SAS_SMP_PHY_T * curr_smp_phy = NULL;
1194 SCIF_SAS_REMOTE_DEVICE_T * current_device = NULL;
1196 while (element != NULL)
1198 curr_smp_phy = (SCIF_SAS_SMP_PHY_T*) sci_fast_list_get_object(element);
1199 element = sci_fast_list_get_next(element);
1201 if ( curr_smp_phy->attached_device_type != SMP_NO_DEVICE_ATTACHED
1202 && curr_smp_phy->u.end_device != NULL )
1204 if (curr_smp_phy->attached_device_type == SMP_END_DEVICE_ONLY)
1205 current_device = curr_smp_phy->u.end_device;
1207 current_device = curr_smp_phy->u.attached_phy->owning_device;
1209 scif_cb_domain_device_removed(fw_domain->controller, fw_domain, current_device);
1213 //remove device itself
1214 scif_cb_domain_device_removed(fw_domain->controller, fw_domain, fw_device);
1219 * @brief This method searches the whole domain and finds all the smp devices to
1220 * cancel their smp activities if there is any.
1222 * @param[in] fw_domain The domain that its smp activities are to be canceled.
1226 void scif_sas_domain_cancel_smp_activities(
1227 SCIF_SAS_DOMAIN_T * fw_domain
1230 SCI_ABSTRACT_ELEMENT_T * current_element =
1231 sci_abstract_list_get_front(&fw_domain->remote_device_list);
1233 SCIF_SAS_REMOTE_DEVICE_T * current_device;
1235 //purge all the outstanding internal IOs in HPQ.
1236 scif_sas_high_priority_request_queue_purge_domain(
1237 &fw_domain->controller->hprq, fw_domain
1240 while ( current_element != NULL )
1242 SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols;
1244 current_device = (SCIF_SAS_REMOTE_DEVICE_T *)
1245 sci_abstract_list_get_object(current_element);
1247 scic_remote_device_get_protocols(current_device->core_object,
1251 if (dev_protocols.u.bits.attached_smp_target)
1253 scif_sas_smp_remote_device_cancel_smp_activity(current_device);
1257 sci_abstract_list_get_next(current_element);
1263 * @brief This method searches the domain's request list and counts outstanding
1266 * @param[in] fw_domain The domain that its request list is to be searched.
1268 * @return U8 The possible return value of this routine is 0 or 1.
1270 U8 scif_sas_domain_get_smp_request_count(
1271 SCIF_SAS_DOMAIN_T * fw_domain
1274 SCI_FAST_LIST_ELEMENT_T * element = fw_domain->request_list.list_head;
1275 SCIF_SAS_REQUEST_T * request = NULL;
1277 SCIC_TRANSPORT_PROTOCOL protocol;
1279 // Cycle through the fast list of IO requests. Terminate each
1280 // outstanding requests that matches the criteria supplied by the
1282 while (element != NULL)
1284 request = (SCIF_SAS_REQUEST_T*) sci_fast_list_get_object(element);
1285 // The current element may be deleted from the list because of
1286 // IO completion so advance to the next element early
1287 element = sci_fast_list_get_next(element);
1289 protocol = scic_io_request_get_protocol(request->core_object);
1291 if ( protocol == SCIC_SMP_PROTOCOL)
1300 * @brief This method start clear affiliation activities for smp devices in
1303 * @param[in] fw_domain The domain that its smp devices are scheduled to clear
1304 * affiliation for all the EA SATA devices.
1308 void scif_sas_domain_start_clear_affiliation(
1309 SCIF_SAS_DOMAIN_T * fw_domain
1312 scif_sas_domain_schedule_clear_affiliation(fw_domain);
1313 scif_sas_domain_continue_clear_affiliation(fw_domain);
1318 * @brief This method schedule clear affiliation activities for smp devices in
1321 * @param[in] fw_domain The domain that its smp devices are scheduled to clear
1322 * affiliation for all the EA SATA devices.
1326 void scif_sas_domain_schedule_clear_affiliation(
1327 SCIF_SAS_DOMAIN_T * fw_domain
1330 SCI_ABSTRACT_ELEMENT_T * current_element =
1331 sci_abstract_list_get_front(&fw_domain->remote_device_list);
1333 SCIF_SAS_REMOTE_DEVICE_T * current_device;
1334 SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols;
1336 //config route table activity has higher priority than discover activity.
1337 while ( current_element != NULL )
1339 current_device = (SCIF_SAS_REMOTE_DEVICE_T *)
1340 sci_abstract_list_get_object(current_element);
1342 scic_remote_device_get_protocols(current_device->core_object,
1346 sci_abstract_list_get_next(current_element);
1348 if ( dev_protocols.u.bits.attached_smp_target )
1350 current_device->protocol_device.smp_device.scheduled_activity =
1351 SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_CLEAR_AFFILIATION;
1358 * @brief This method carries clear affiliation activities for a smp devices in
1359 * this domain during controller stop process.
1361 * @param[in] fw_domain The domain that its smp devices are to clear
1362 * affiliation for all the EA SATA devices.
1366 void scif_sas_domain_continue_clear_affiliation(
1367 SCIF_SAS_DOMAIN_T * fw_domain
1370 SCIF_SAS_REMOTE_DEVICE_T * smp_device =
1371 scif_sas_domain_find_device_has_scheduled_activity(
1373 SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_CLEAR_AFFILIATION
1376 if (smp_device != NULL)
1377 scif_sas_smp_remote_device_start_clear_affiliation(smp_device);
1380 //This domain has done clear affiliation.
1381 SCIF_SAS_CONTROLLER_T * fw_controller = fw_domain->controller;
1382 fw_controller->current_domain_to_clear_affiliation++;
1384 //let controller continue to clear affiliation on other domains.
1385 scif_sas_controller_clear_affiliation(fw_domain->controller);
1391 * @brief This method releases resource for a framework domain.
1393 * @param[in] fw_controller This parameter specifies the framework
1394 * controller, its associated domain's resources are to be released.
1395 * @param[in] fw_domain This parameter specifies the framework
1396 * domain whose resources are to be released.
1398 void scif_sas_domain_release_resource(
1399 SCIF_SAS_CONTROLLER_T * fw_controller,
1400 SCIF_SAS_DOMAIN_T * fw_domain
1403 if (fw_domain->operation.timer != NULL)
1405 scif_cb_timer_destroy(fw_controller, fw_domain->operation.timer);
1406 fw_domain->operation.timer = NULL;
1412 * @brief This method finds the a EA device that has target reset scheduled.
1414 * @param[in] fw_domain The framework domain object
1416 * @return SCIF_SAS_REMOTE_DEVICE_T The EA device that has target reset scheduled.
1418 SCIF_SAS_REMOTE_DEVICE_T * scif_sas_domain_find_next_ea_target_reset(
1419 SCIF_SAS_DOMAIN_T * fw_domain
1422 SCI_ABSTRACT_ELEMENT_T * current_element;
1423 SCIF_SAS_REMOTE_DEVICE_T * current_device;
1426 sci_base_object_get_logger(fw_domain),
1427 SCIF_LOG_OBJECT_DOMAIN,
1428 "scif_sas_domain_find_next_ea_target_reset(0x%x) enter\n",
1432 //search through domain's device list to find the first sata device on spinup_hold
1433 current_element = sci_abstract_list_get_front(&fw_domain->remote_device_list);
1434 while (current_element != NULL )
1436 current_device = (SCIF_SAS_REMOTE_DEVICE_T *)
1437 sci_abstract_list_get_object(current_element);
1439 current_element = sci_abstract_list_get_next(current_element);
1441 if ( current_device->ea_target_reset_request_scheduled != NULL )
1443 return current_device;
1450 #if !defined(DISABLE_WIDE_PORTED_TARGETS)
1452 * @brief This method update the direct attached device port width.
1454 * @param[in] fw_domain The framework domain object
1455 * @param[in] port The associated port object which recently has link up/down
1460 void scif_sas_domain_update_device_port_width(
1461 SCIF_SAS_DOMAIN_T * fw_domain,
1462 SCI_PORT_HANDLE_T port
1465 SCIF_SAS_REMOTE_DEVICE_T * fw_device;
1466 SCIC_PORT_PROPERTIES_T properties;
1467 U8 new_port_width = 0;
1470 sci_base_object_get_logger(fw_domain),
1471 SCIF_LOG_OBJECT_DOMAIN,
1472 "scif_sas_domain_update_device_port_width(0x%x, 0x%x) enter\n",
1476 scic_port_get_properties(port, &properties);
1478 fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)
1479 scif_domain_get_device_by_sas_address(
1480 fw_domain, &properties.remote.sas_address
1483 // If the device already existed in the domain, it is a wide port SSP target,
1484 // we need to update its port width.
1485 if (fw_device != SCI_INVALID_HANDLE)
1487 SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols;
1488 scic_remote_device_get_protocols(fw_device->core_object, &dev_protocols);
1490 if (dev_protocols.u.bits.attached_ssp_target)
1492 //Get accurate port width from port's phy mask for a DA device.
1493 SCI_GET_BITS_SET_COUNT(properties.phy_mask, new_port_width);
1495 scif_sas_remote_device_update_port_width(fw_device, new_port_width);
1499 #endif //#if !defined(DISABLE_WIDE_PORTED_TARGETS)
1504 * This method will turn on logging of domain state changes.
1506 * @param[in] fw_domain The domain for which the state logging is to be turned
1509 void scif_sas_domain_initialize_state_logging(
1510 SCIF_SAS_DOMAIN_T *fw_domain
1513 sci_base_state_machine_logger_initialize(
1514 &fw_domain->parent.state_machine_logger,
1515 &fw_domain->parent.state_machine,
1516 &fw_domain->parent.parent,
1517 scif_cb_logger_log_states,
1518 "SCIF_SAS_DOMAIN_T", "base state machine",
1519 SCIF_LOG_OBJECT_DOMAIN
1524 * This method will turn off logging of domain state changes.
1526 * @param[in] fw_domain The domain for which the state logging is to be turned
1529 void scif_sas_domain_deinitialize_state_logging(
1530 SCIF_SAS_DOMAIN_T *fw_domain
1533 sci_base_state_machine_logger_deinitialize(
1534 &fw_domain->parent.state_machine_logger,
1535 &fw_domain->parent.state_machine