1f11c7f63SJim Harris /*-
2*718cf2ccSPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
3*718cf2ccSPedro F. Giffuni *
4f11c7f63SJim Harris * This file is provided under a dual BSD/GPLv2 license. When using or
5f11c7f63SJim Harris * redistributing this file, you may do so under either license.
6f11c7f63SJim Harris *
7f11c7f63SJim Harris * GPL LICENSE SUMMARY
8f11c7f63SJim Harris *
9f11c7f63SJim Harris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
10f11c7f63SJim Harris *
11f11c7f63SJim Harris * This program is free software; you can redistribute it and/or modify
12f11c7f63SJim Harris * it under the terms of version 2 of the GNU General Public License as
13f11c7f63SJim Harris * published by the Free Software Foundation.
14f11c7f63SJim Harris *
15f11c7f63SJim Harris * This program is distributed in the hope that it will be useful, but
16f11c7f63SJim Harris * WITHOUT ANY WARRANTY; without even the implied warranty of
17f11c7f63SJim Harris * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18f11c7f63SJim Harris * General Public License for more details.
19f11c7f63SJim Harris *
20f11c7f63SJim Harris * You should have received a copy of the GNU General Public License
21f11c7f63SJim Harris * along with this program; if not, write to the Free Software
22f11c7f63SJim Harris * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
23f11c7f63SJim Harris * The full GNU General Public License is included in this distribution
24f11c7f63SJim Harris * in the file called LICENSE.GPL.
25f11c7f63SJim Harris *
26f11c7f63SJim Harris * BSD LICENSE
27f11c7f63SJim Harris *
28f11c7f63SJim Harris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
29f11c7f63SJim Harris * All rights reserved.
30f11c7f63SJim Harris *
31f11c7f63SJim Harris * Redistribution and use in source and binary forms, with or without
32f11c7f63SJim Harris * modification, are permitted provided that the following conditions
33f11c7f63SJim Harris * are met:
34f11c7f63SJim Harris *
35f11c7f63SJim Harris * * Redistributions of source code must retain the above copyright
36f11c7f63SJim Harris * notice, this list of conditions and the following disclaimer.
37f11c7f63SJim Harris * * Redistributions in binary form must reproduce the above copyright
38f11c7f63SJim Harris * notice, this list of conditions and the following disclaimer in
39f11c7f63SJim Harris * the documentation and/or other materials provided with the
40f11c7f63SJim Harris * distribution.
41f11c7f63SJim Harris *
42f11c7f63SJim Harris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43f11c7f63SJim Harris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44f11c7f63SJim Harris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
45f11c7f63SJim Harris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
46f11c7f63SJim Harris * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47f11c7f63SJim Harris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
48f11c7f63SJim Harris * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
49f11c7f63SJim Harris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50f11c7f63SJim Harris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51f11c7f63SJim Harris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52f11c7f63SJim Harris * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53f11c7f63SJim Harris */
54f11c7f63SJim Harris
55f11c7f63SJim Harris #include <sys/cdefs.h>
56f11c7f63SJim Harris /**
57f11c7f63SJim Harris * @file
58f11c7f63SJim Harris *
59f11c7f63SJim Harris * @brief This file contains the implementation of the SCIF_SAS_DOMAIN
60f11c7f63SJim Harris * object.
61f11c7f63SJim Harris */
62f11c7f63SJim Harris
63f11c7f63SJim Harris #include <dev/isci/scil/intel_sas.h>
64f11c7f63SJim Harris #include <dev/isci/scil/sci_fast_list.h>
65f11c7f63SJim Harris #include <dev/isci/scil/scic_controller.h>
66f11c7f63SJim Harris #include <dev/isci/scil/scic_port.h>
67f11c7f63SJim Harris #include <dev/isci/scil/scic_remote_device.h>
68f11c7f63SJim Harris #include <dev/isci/scil/scic_io_request.h>
69f11c7f63SJim Harris #include <dev/isci/scil/scic_user_callback.h>
70f11c7f63SJim Harris #include <dev/isci/scil/scif_user_callback.h>
71f11c7f63SJim Harris #include <dev/isci/scil/sci_abstract_list.h>
72f11c7f63SJim Harris #include <dev/isci/scil/sci_base_iterator.h>
73f11c7f63SJim Harris
74f11c7f63SJim Harris #include <dev/isci/scil/scif_sas_logger.h>
75f11c7f63SJim Harris #include <dev/isci/scil/scif_sas_domain.h>
76f11c7f63SJim Harris #include <dev/isci/scil/scif_sas_controller.h>
77f11c7f63SJim Harris #include <dev/isci/scil/scif_sas_remote_device.h>
78f11c7f63SJim Harris #include <dev/isci/scil/scif_sas_smp_remote_device.h>
79f11c7f63SJim Harris #include <dev/isci/scil/sci_util.h>
80f11c7f63SJim Harris
81f11c7f63SJim Harris //******************************************************************************
82f11c7f63SJim Harris //* P R I V A T E M E T H O D S
83f11c7f63SJim Harris //******************************************************************************
84f11c7f63SJim Harris
85f11c7f63SJim Harris /**
86f11c7f63SJim Harris * @brief This method will attempt to handle an operation timeout (i.e.
87f11c7f63SJim Harris * discovery or reset).
88f11c7f63SJim Harris *
89f11c7f63SJim Harris * @param[in] cookie This parameter specifies the domain in which the
90f11c7f63SJim Harris * timeout occurred.
91f11c7f63SJim Harris *
92f11c7f63SJim Harris * @return none
93f11c7f63SJim Harris */
94f11c7f63SJim Harris static
scif_sas_domain_operation_timeout_handler(void * cookie)95f11c7f63SJim Harris void scif_sas_domain_operation_timeout_handler(
96f11c7f63SJim Harris void * cookie
97f11c7f63SJim Harris )
98f11c7f63SJim Harris {
99f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*) cookie;
100f11c7f63SJim Harris U32 state;
101f11c7f63SJim Harris
102f11c7f63SJim Harris state = sci_base_state_machine_get_state(&fw_domain->parent.state_machine);
103f11c7f63SJim Harris
104f11c7f63SJim Harris // Based upon the state of the domain, we know whether we were in the
105f11c7f63SJim Harris // process of performing discovery or a reset.
106f11c7f63SJim Harris if (state == SCI_BASE_DOMAIN_STATE_DISCOVERING)
107f11c7f63SJim Harris {
108f11c7f63SJim Harris SCIF_LOG_WARNING((
109f11c7f63SJim Harris sci_base_object_get_logger(fw_domain),
110f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN,
111f11c7f63SJim Harris "Domain:0x%x State:0x%x DISCOVER timeout!\n",
112f11c7f63SJim Harris fw_domain, state
113f11c7f63SJim Harris ));
114f11c7f63SJim Harris
115f11c7f63SJim Harris fw_domain->operation.status = SCI_FAILURE_TIMEOUT;
116f11c7f63SJim Harris
117f11c7f63SJim Harris //search all the smp devices in the domain and cancel their activities
118f11c7f63SJim Harris //if there is any outstanding activity remained. The smp devices will terminate
119f11c7f63SJim Harris //all the started internal IOs.
120f11c7f63SJim Harris scif_sas_domain_cancel_smp_activities(fw_domain);
121f11c7f63SJim Harris
122f11c7f63SJim Harris scif_sas_domain_continue_discover(fw_domain);
123f11c7f63SJim Harris }
124f11c7f63SJim Harris else
125f11c7f63SJim Harris {
126f11c7f63SJim Harris SCIF_LOG_ERROR((
127f11c7f63SJim Harris sci_base_object_get_logger(fw_domain),
128f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN,
129f11c7f63SJim Harris "Domain:0x%x State:0x%x operation timeout in invalid state\n",
130f11c7f63SJim Harris fw_domain, state
131f11c7f63SJim Harris ));
132f11c7f63SJim Harris }
133f11c7f63SJim Harris }
134f11c7f63SJim Harris
135f11c7f63SJim Harris //******************************************************************************
136f11c7f63SJim Harris //* P U B L I C M E T H O D S
137f11c7f63SJim Harris //******************************************************************************
138f11c7f63SJim Harris
scif_domain_get_scic_port_handle(SCI_DOMAIN_HANDLE_T domain)139f11c7f63SJim Harris SCI_PORT_HANDLE_T scif_domain_get_scic_port_handle(
140f11c7f63SJim Harris SCI_DOMAIN_HANDLE_T domain
141f11c7f63SJim Harris )
142f11c7f63SJim Harris {
143f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*) domain;
144f11c7f63SJim Harris
1452d57bb86SJim Harris if ( (fw_domain == NULL) || (fw_domain->core_object == SCI_INVALID_HANDLE) )
1462d57bb86SJim Harris return SCI_INVALID_HANDLE;
147f11c7f63SJim Harris
148f11c7f63SJim Harris SCIF_LOG_WARNING((
149f11c7f63SJim Harris sci_base_object_get_logger(fw_domain),
150f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN,
151f11c7f63SJim Harris "Domain:0x%x no associated core port found\n",
152f11c7f63SJim Harris fw_domain
153f11c7f63SJim Harris ));
154f11c7f63SJim Harris
1552d57bb86SJim Harris return fw_domain->core_object;
156f11c7f63SJim Harris }
157f11c7f63SJim Harris
158f11c7f63SJim Harris // ---------------------------------------------------------------------------
159f11c7f63SJim Harris
scif_domain_get_device_by_sas_address(SCI_DOMAIN_HANDLE_T domain,SCI_SAS_ADDRESS_T * sas_address)160f11c7f63SJim Harris SCI_REMOTE_DEVICE_HANDLE_T scif_domain_get_device_by_sas_address(
161f11c7f63SJim Harris SCI_DOMAIN_HANDLE_T domain,
162f11c7f63SJim Harris SCI_SAS_ADDRESS_T * sas_address
163f11c7f63SJim Harris )
164f11c7f63SJim Harris {
165f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*) domain;
166f11c7f63SJim Harris SCI_ABSTRACT_ELEMENT_T * element = sci_abstract_list_get_front(
167f11c7f63SJim Harris &fw_domain->remote_device_list
168f11c7f63SJim Harris );
169f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * fw_device;
170f11c7f63SJim Harris SCI_SAS_ADDRESS_T fw_device_address;
171f11c7f63SJim Harris
172f11c7f63SJim Harris SCIF_LOG_TRACE((
173f11c7f63SJim Harris sci_base_object_get_logger(domain),
174f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN,
175f11c7f63SJim Harris "scif_domain_get_device_by_sas_address(0x%x, 0x%x) enter\n",
176f11c7f63SJim Harris domain, sas_address
177f11c7f63SJim Harris ));
178f11c7f63SJim Harris
179f11c7f63SJim Harris // Search the abstract list to see if there is a remote device with the
180f11c7f63SJim Harris // same SAS address.
181f11c7f63SJim Harris while (element != NULL)
182f11c7f63SJim Harris {
183f11c7f63SJim Harris fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
184f11c7f63SJim Harris sci_abstract_list_get_object(element);
185f11c7f63SJim Harris
186f11c7f63SJim Harris scic_remote_device_get_sas_address(
187f11c7f63SJim Harris fw_device->core_object, &fw_device_address
188f11c7f63SJim Harris );
189f11c7f63SJim Harris
190f11c7f63SJim Harris // Check to see if this is the device for which we are searching.
191f11c7f63SJim Harris if ( (fw_device_address.low == sas_address->low)
192f11c7f63SJim Harris && (fw_device_address.high == sas_address->high) )
193f11c7f63SJim Harris {
194f11c7f63SJim Harris return fw_device;
195f11c7f63SJim Harris }
196f11c7f63SJim Harris
197f11c7f63SJim Harris element = sci_abstract_list_get_next(element);
198f11c7f63SJim Harris }
199f11c7f63SJim Harris
200f11c7f63SJim Harris return SCI_INVALID_HANDLE;
201f11c7f63SJim Harris }
202f11c7f63SJim Harris
203f11c7f63SJim Harris // ---------------------------------------------------------------------------
204f11c7f63SJim Harris
205f11c7f63SJim Harris #if !defined(DISABLE_SCI_ITERATORS)
206f11c7f63SJim Harris
scif_domain_get_remote_device_iterator(SCI_DOMAIN_HANDLE_T domain,void * iterator_buffer)207f11c7f63SJim Harris SCI_ITERATOR_HANDLE_T scif_domain_get_remote_device_iterator(
208f11c7f63SJim Harris SCI_DOMAIN_HANDLE_T domain,
209f11c7f63SJim Harris void * iterator_buffer
210f11c7f63SJim Harris )
211f11c7f63SJim Harris {
212f11c7f63SJim Harris SCI_ITERATOR_HANDLE_T iterator = (SCI_ITERATOR_HANDLE_T *)iterator_buffer;
213f11c7f63SJim Harris
214f11c7f63SJim Harris sci_base_iterator_construct(
215f11c7f63SJim Harris iterator, &((SCIF_SAS_DOMAIN_T*) domain)->remote_device_list
216f11c7f63SJim Harris );
217f11c7f63SJim Harris
218f11c7f63SJim Harris
219f11c7f63SJim Harris return iterator;
220f11c7f63SJim Harris }
221f11c7f63SJim Harris
222f11c7f63SJim Harris #endif // !defined(DISABLE_SCI_ITERATORS)
223f11c7f63SJim Harris
224f11c7f63SJim Harris // ---------------------------------------------------------------------------
225f11c7f63SJim Harris
scif_domain_discover(SCI_DOMAIN_HANDLE_T domain,U32 discover_timeout,U32 device_timeout)226f11c7f63SJim Harris SCI_STATUS scif_domain_discover(
227f11c7f63SJim Harris SCI_DOMAIN_HANDLE_T domain,
228f11c7f63SJim Harris U32 discover_timeout,
229f11c7f63SJim Harris U32 device_timeout
230f11c7f63SJim Harris )
231f11c7f63SJim Harris {
232f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*) domain;
233f11c7f63SJim Harris SCI_STATUS status = SCI_SUCCESS;
234f11c7f63SJim Harris SCI_STATUS op_status = SCI_SUCCESS;
235f11c7f63SJim Harris
236f11c7f63SJim Harris SCIF_LOG_TRACE((
237f11c7f63SJim Harris sci_base_object_get_logger(domain),
238f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
239f11c7f63SJim Harris "scif_domain_discover(0x%x, 0x%x, 0x%x) enter\n",
240f11c7f63SJim Harris domain, discover_timeout, device_timeout
241f11c7f63SJim Harris ));
242f11c7f63SJim Harris
243f11c7f63SJim Harris // Check to make sure the size of the domain doesn't cause potential issues
244f11c7f63SJim Harris // with the remote device timer and the domain timer.
245f11c7f63SJim Harris if ((device_timeout * sci_abstract_list_size(&fw_domain->remote_device_list))
246f11c7f63SJim Harris > discover_timeout)
247f11c7f63SJim Harris status = SCI_WARNING_TIMER_CONFLICT;
248f11c7f63SJim Harris
249f11c7f63SJim Harris op_status = fw_domain->state_handlers->discover_handler(
250f11c7f63SJim Harris &fw_domain->parent, discover_timeout, device_timeout
251f11c7f63SJim Harris );
252f11c7f63SJim Harris
253f11c7f63SJim Harris // The status of the discover operation takes priority.
254f11c7f63SJim Harris if ( (status == SCI_SUCCESS)
255f11c7f63SJim Harris || (status != SCI_SUCCESS && op_status != SCI_SUCCESS) )
256f11c7f63SJim Harris {
257f11c7f63SJim Harris status = op_status;
258f11c7f63SJim Harris }
259f11c7f63SJim Harris
260f11c7f63SJim Harris return status;
261f11c7f63SJim Harris }
262f11c7f63SJim Harris
263f11c7f63SJim Harris // ---------------------------------------------------------------------------
264f11c7f63SJim Harris
scif_domain_get_suggested_discover_timeout(SCI_DOMAIN_HANDLE_T domain)265f11c7f63SJim Harris U32 scif_domain_get_suggested_discover_timeout(
266f11c7f63SJim Harris SCI_DOMAIN_HANDLE_T domain
267f11c7f63SJim Harris )
268f11c7f63SJim Harris {
269f11c7f63SJim Harris U32 suggested_timeout = SCIF_DOMAIN_DISCOVER_TIMEOUT; //milli-seconds
270f11c7f63SJim Harris return suggested_timeout;
271f11c7f63SJim Harris }
272f11c7f63SJim Harris
273f11c7f63SJim Harris // ---------------------------------------------------------------------------
274f11c7f63SJim Harris
scic_cb_port_stop_complete(SCI_CONTROLLER_HANDLE_T controller,SCI_PORT_HANDLE_T port,SCI_STATUS completion_status)275f11c7f63SJim Harris void scic_cb_port_stop_complete(
276f11c7f63SJim Harris SCI_CONTROLLER_HANDLE_T controller,
277f11c7f63SJim Harris SCI_PORT_HANDLE_T port,
278f11c7f63SJim Harris SCI_STATUS completion_status
279f11c7f63SJim Harris )
280f11c7f63SJim Harris {
281f11c7f63SJim Harris SCIF_LOG_TRACE((
282f11c7f63SJim Harris sci_base_object_get_logger((SCIF_SAS_DOMAIN_T*)sci_object_get_association(port)),
283f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN,
284f11c7f63SJim Harris "scic_cb_port_stop_complete(0x%x, 0x%x, 0x%x) enter\n",
285f11c7f63SJim Harris controller, port, completion_status
286f11c7f63SJim Harris ));
287f11c7f63SJim Harris }
288f11c7f63SJim Harris
289f11c7f63SJim Harris // ---------------------------------------------------------------------------
290f11c7f63SJim Harris
scic_cb_port_ready(SCI_CONTROLLER_HANDLE_T controller,SCI_PORT_HANDLE_T port)291f11c7f63SJim Harris void scic_cb_port_ready(
292f11c7f63SJim Harris SCI_CONTROLLER_HANDLE_T controller,
293f11c7f63SJim Harris SCI_PORT_HANDLE_T port
294f11c7f63SJim Harris )
295f11c7f63SJim Harris {
296f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*)
297f11c7f63SJim Harris sci_object_get_association(port);
298f11c7f63SJim Harris
299f11c7f63SJim Harris SCIF_LOG_TRACE((
300f11c7f63SJim Harris sci_base_object_get_logger(fw_domain),
301f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN,
302f11c7f63SJim Harris "scic_cb_port_ready(0x%x, 0x%x) enter\n",
303f11c7f63SJim Harris controller, port
304f11c7f63SJim Harris ));
305f11c7f63SJim Harris
306f11c7f63SJim Harris // The controller supplied with the port should match the controller
307f11c7f63SJim Harris // saved in the domain.
308f11c7f63SJim Harris ASSERT(sci_object_get_association(controller) == fw_domain->controller);
309f11c7f63SJim Harris
310f11c7f63SJim Harris fw_domain->is_port_ready = TRUE;
311f11c7f63SJim Harris
312f11c7f63SJim Harris fw_domain->state_handlers->port_ready_handler(&fw_domain->parent);
313f11c7f63SJim Harris }
314f11c7f63SJim Harris
315f11c7f63SJim Harris // ---------------------------------------------------------------------------
316f11c7f63SJim Harris
scic_cb_port_not_ready(SCI_CONTROLLER_HANDLE_T controller,SCI_PORT_HANDLE_T port,U32 reason_code)317f11c7f63SJim Harris void scic_cb_port_not_ready(
318f11c7f63SJim Harris SCI_CONTROLLER_HANDLE_T controller,
319f11c7f63SJim Harris SCI_PORT_HANDLE_T port,
320f11c7f63SJim Harris U32 reason_code
321f11c7f63SJim Harris )
322f11c7f63SJim Harris {
323f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*)
324f11c7f63SJim Harris sci_object_get_association(port);
325f11c7f63SJim Harris
326f11c7f63SJim Harris SCIF_LOG_TRACE((
327f11c7f63SJim Harris sci_base_object_get_logger(fw_domain),
328f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN,
329f11c7f63SJim Harris "scic_cb_port_not_ready(0x%x, 0x%x) enter\n",
330f11c7f63SJim Harris controller, port
331f11c7f63SJim Harris ));
332f11c7f63SJim Harris
333f11c7f63SJim Harris // The controller supplied with the port should match the controller
334f11c7f63SJim Harris // saved in the domain.
335f11c7f63SJim Harris ASSERT(sci_object_get_association(controller) == fw_domain->controller);
336f11c7f63SJim Harris
337f11c7f63SJim Harris // There is no need to take action on the port reconfiguring since it is
338f11c7f63SJim Harris // just a change of the port width.
339f11c7f63SJim Harris if (reason_code != SCIC_PORT_NOT_READY_RECONFIGURING)
340f11c7f63SJim Harris {
341f11c7f63SJim Harris fw_domain->is_port_ready = FALSE;
342f11c7f63SJim Harris
343f11c7f63SJim Harris fw_domain->state_handlers->port_not_ready_handler(
344f11c7f63SJim Harris &fw_domain->parent, reason_code);
345f11c7f63SJim Harris }
346f11c7f63SJim Harris }
347f11c7f63SJim Harris
348f11c7f63SJim Harris // ---------------------------------------------------------------------------
349f11c7f63SJim Harris
scic_cb_port_hard_reset_complete(SCI_CONTROLLER_HANDLE_T controller,SCI_PORT_HANDLE_T port,SCI_STATUS completion_status)350f11c7f63SJim Harris void scic_cb_port_hard_reset_complete(
351f11c7f63SJim Harris SCI_CONTROLLER_HANDLE_T controller,
352f11c7f63SJim Harris SCI_PORT_HANDLE_T port,
353f11c7f63SJim Harris SCI_STATUS completion_status
354f11c7f63SJim Harris )
355f11c7f63SJim Harris {
356f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*)
357f11c7f63SJim Harris sci_object_get_association(port);
358f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * fw_device;
359f11c7f63SJim Harris SCI_FAST_LIST_ELEMENT_T * element = fw_domain->request_list.list_head;
360f11c7f63SJim Harris SCIF_SAS_TASK_REQUEST_T * task_request = NULL;
361f11c7f63SJim Harris
362f11c7f63SJim Harris SCIF_LOG_TRACE((
363f11c7f63SJim Harris sci_base_object_get_logger(fw_domain),
364f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN,
365f11c7f63SJim Harris "scic_cb_port_hard_reset_complete(0x%x, 0x%x, 0x%x) enter\n",
366f11c7f63SJim Harris controller, port, completion_status
367f11c7f63SJim Harris ));
368f11c7f63SJim Harris
369f11c7f63SJim Harris while (element != NULL)
370f11c7f63SJim Harris {
371f11c7f63SJim Harris task_request = (SCIF_SAS_TASK_REQUEST_T*) sci_fast_list_get_object(element);
372f11c7f63SJim Harris element = sci_fast_list_get_next(element);
373f11c7f63SJim Harris
374f11c7f63SJim Harris if (scif_sas_task_request_get_function(task_request)
375f11c7f63SJim Harris == SCI_SAS_HARD_RESET)
376f11c7f63SJim Harris {
377f11c7f63SJim Harris fw_device = task_request->parent.device;
378f11c7f63SJim Harris
379f11c7f63SJim Harris if (fw_device->domain == fw_domain)
380f11c7f63SJim Harris {
381f11c7f63SJim Harris scic_remote_device_reset_complete(fw_device->core_object);
382f11c7f63SJim Harris
383f11c7f63SJim Harris scif_cb_task_request_complete(
384f11c7f63SJim Harris sci_object_get_association(controller),
385f11c7f63SJim Harris fw_device,
386f11c7f63SJim Harris task_request,
387f11c7f63SJim Harris (SCI_TASK_STATUS) completion_status
388f11c7f63SJim Harris );
389f11c7f63SJim Harris
390f11c7f63SJim Harris break;
391f11c7f63SJim Harris }
392f11c7f63SJim Harris }
393f11c7f63SJim Harris }
394f11c7f63SJim Harris }
395f11c7f63SJim Harris
396f11c7f63SJim Harris // ---------------------------------------------------------------------------
397f11c7f63SJim Harris
scic_cb_port_bc_change_primitive_recieved(SCI_CONTROLLER_HANDLE_T controller,SCI_PORT_HANDLE_T port,SCI_PHY_HANDLE_T phy)398f11c7f63SJim Harris void scic_cb_port_bc_change_primitive_recieved(
399f11c7f63SJim Harris SCI_CONTROLLER_HANDLE_T controller,
400f11c7f63SJim Harris SCI_PORT_HANDLE_T port,
401f11c7f63SJim Harris SCI_PHY_HANDLE_T phy
402f11c7f63SJim Harris )
403f11c7f63SJim Harris {
404f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*)
405f11c7f63SJim Harris sci_object_get_association(port);
406f11c7f63SJim Harris
407f11c7f63SJim Harris SCIF_SAS_CONTROLLER_T * fw_controller = (SCIF_SAS_CONTROLLER_T *)
408f11c7f63SJim Harris sci_object_get_association(controller);
409f11c7f63SJim Harris
410f11c7f63SJim Harris SCIF_LOG_TRACE((
411f11c7f63SJim Harris sci_base_object_get_logger(fw_domain),
412f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
413f11c7f63SJim Harris "scic_cb_port_bc_change_primitive_recieved(0x%x, 0x%x, 0x%x) enter\n",
414f11c7f63SJim Harris controller, port, phy
415f11c7f63SJim Harris ));
416f11c7f63SJim Harris
417f11c7f63SJim Harris if (fw_domain->broadcast_change_count == 0)
418f11c7f63SJim Harris { // Enable the BCN detection only if the bcn_count is zero. If bcn_count is
419f11c7f63SJim Harris // not zero at this time, we won't enable BCN detection since all non-zero
420f11c7f63SJim Harris // BCN_count means same to us. Furthermore, we avoid BCN storm by not
421f11c7f63SJim Harris // always enabling the BCN_detection.
422f11c7f63SJim Harris scic_port_enable_broadcast_change_notification(fw_domain->core_object);
423f11c7f63SJim Harris }
424f11c7f63SJim Harris
425f11c7f63SJim Harris fw_domain->broadcast_change_count++;
426f11c7f63SJim Harris
427f11c7f63SJim Harris //if there is smp device on this domain that is in the middle of discover
428f11c7f63SJim Harris //process or smp target reset, don't notify the driver layer.
429f11c7f63SJim Harris if( ! scif_sas_domain_is_in_smp_activity(fw_domain) )
430f11c7f63SJim Harris // Notify the user that there is, potentially, a change to the domain.
431f11c7f63SJim Harris scif_cb_domain_change_notification(fw_controller, fw_domain);
432f11c7f63SJim Harris }
433f11c7f63SJim Harris
434f11c7f63SJim Harris // ---------------------------------------------------------------------------
435f11c7f63SJim Harris
scic_cb_port_bc_ses_primitive_recieved(SCI_CONTROLLER_HANDLE_T controller,SCI_PORT_HANDLE_T port,SCI_PHY_HANDLE_T phy)436f11c7f63SJim Harris void scic_cb_port_bc_ses_primitive_recieved(
437f11c7f63SJim Harris SCI_CONTROLLER_HANDLE_T controller,
438f11c7f63SJim Harris SCI_PORT_HANDLE_T port,
439f11c7f63SJim Harris SCI_PHY_HANDLE_T phy
440f11c7f63SJim Harris )
441f11c7f63SJim Harris {
442f11c7f63SJim Harris SCIF_LOG_TRACE((
443f11c7f63SJim Harris sci_base_object_get_logger(sci_object_get_association(port)),
444f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN,
445f11c7f63SJim Harris "scic_cb_port_bc_ses_primitive_received(0x%x, 0x%x, 0x%x) enter\n",
446f11c7f63SJim Harris controller, port, phy
447f11c7f63SJim Harris ));
448f11c7f63SJim Harris }
449f11c7f63SJim Harris
450f11c7f63SJim Harris // ---------------------------------------------------------------------------
451f11c7f63SJim Harris
scic_cb_port_bc_expander_primitive_recieved(SCI_CONTROLLER_HANDLE_T controller,SCI_PORT_HANDLE_T port,SCI_PHY_HANDLE_T phy)452f11c7f63SJim Harris void scic_cb_port_bc_expander_primitive_recieved(
453f11c7f63SJim Harris SCI_CONTROLLER_HANDLE_T controller,
454f11c7f63SJim Harris SCI_PORT_HANDLE_T port,
455f11c7f63SJim Harris SCI_PHY_HANDLE_T phy
456f11c7f63SJim Harris )
457f11c7f63SJim Harris {
458f11c7f63SJim Harris SCIF_LOG_TRACE((
459f11c7f63SJim Harris sci_base_object_get_logger(sci_object_get_association(port)),
460f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN,
461f11c7f63SJim Harris "scic_cb_port_bc_expander_primitive_received(0x%x, 0x%x, 0x%x) enter\n",
462f11c7f63SJim Harris controller, port, phy
463f11c7f63SJim Harris ));
464f11c7f63SJim Harris }
465f11c7f63SJim Harris
466f11c7f63SJim Harris // ---------------------------------------------------------------------------
467f11c7f63SJim Harris
scic_cb_port_bc_aen_primitive_recieved(SCI_CONTROLLER_HANDLE_T controller,SCI_PORT_HANDLE_T port,SCI_PHY_HANDLE_T phy)468f11c7f63SJim Harris void scic_cb_port_bc_aen_primitive_recieved(
469f11c7f63SJim Harris SCI_CONTROLLER_HANDLE_T controller,
470f11c7f63SJim Harris SCI_PORT_HANDLE_T port,
471f11c7f63SJim Harris SCI_PHY_HANDLE_T phy
472f11c7f63SJim Harris )
473f11c7f63SJim Harris {
474f11c7f63SJim Harris SCIF_LOG_TRACE((
475f11c7f63SJim Harris sci_base_object_get_logger(sci_object_get_association(port)),
476f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN,
477f11c7f63SJim Harris "scic_cb_port_bc_aen_primitive_received(0x%x, 0x%x, 0x%x) enter\n",
478f11c7f63SJim Harris controller, port, phy
479f11c7f63SJim Harris ));
480f11c7f63SJim Harris }
481f11c7f63SJim Harris
482f11c7f63SJim Harris // ---------------------------------------------------------------------------
483f11c7f63SJim Harris
scic_cb_port_link_up(SCI_CONTROLLER_HANDLE_T controller,SCI_PORT_HANDLE_T port,SCI_PHY_HANDLE_T phy)484f11c7f63SJim Harris void scic_cb_port_link_up(
485f11c7f63SJim Harris SCI_CONTROLLER_HANDLE_T controller,
486f11c7f63SJim Harris SCI_PORT_HANDLE_T port,
487f11c7f63SJim Harris SCI_PHY_HANDLE_T phy
488f11c7f63SJim Harris )
489f11c7f63SJim Harris {
490f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*)
491f11c7f63SJim Harris sci_object_get_association(port);
492f11c7f63SJim Harris
493f11c7f63SJim Harris SCIF_LOG_TRACE((
494f11c7f63SJim Harris sci_base_object_get_logger(sci_object_get_association(port)),
495f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN,
496f11c7f63SJim Harris "scic_cb_port_link_up(0x%x, 0x%x, 0x%x) enter\n",
497f11c7f63SJim Harris controller, port, phy
498f11c7f63SJim Harris ));
499f11c7f63SJim Harris
500f11c7f63SJim Harris scif_sas_domain_update_device_port_width(fw_domain, port);
501f11c7f63SJim Harris }
502f11c7f63SJim Harris
503f11c7f63SJim Harris // ---------------------------------------------------------------------------
504f11c7f63SJim Harris
scic_cb_port_link_down(SCI_CONTROLLER_HANDLE_T controller,SCI_PORT_HANDLE_T port,SCI_PHY_HANDLE_T phy)505f11c7f63SJim Harris void scic_cb_port_link_down(
506f11c7f63SJim Harris SCI_CONTROLLER_HANDLE_T controller,
507f11c7f63SJim Harris SCI_PORT_HANDLE_T port,
508f11c7f63SJim Harris SCI_PHY_HANDLE_T phy
509f11c7f63SJim Harris )
510f11c7f63SJim Harris {
511f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain = (SCIF_SAS_DOMAIN_T*)
512f11c7f63SJim Harris sci_object_get_association(port);
513f11c7f63SJim Harris
514f11c7f63SJim Harris SCIF_LOG_TRACE((
515f11c7f63SJim Harris sci_base_object_get_logger(sci_object_get_association(port)),
516f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN,
517f11c7f63SJim Harris "scic_cb_port_link_down(0x%x, 0x%x, 0x%x) enter\n",
518f11c7f63SJim Harris controller, port, phy
519f11c7f63SJim Harris ));
520f11c7f63SJim Harris
521f11c7f63SJim Harris scif_sas_domain_update_device_port_width(fw_domain, port);
522f11c7f63SJim Harris }
523f11c7f63SJim Harris
524f11c7f63SJim Harris //******************************************************************************
525f11c7f63SJim Harris //* P R O T E C T E D M E T H O D S
526f11c7f63SJim Harris //******************************************************************************
527f11c7f63SJim Harris
528f11c7f63SJim Harris /**
529f11c7f63SJim Harris * @brief This method constructs the framework's SAS domain object. During
530f11c7f63SJim Harris * the construction process a linkage to the corresponding core port
531f11c7f63SJim Harris * object.
532f11c7f63SJim Harris *
533f11c7f63SJim Harris * @param[in] domain This parameter specifies the domain object to be
534f11c7f63SJim Harris * constructed.
535f11c7f63SJim Harris * @param[in] domain_id This parameter specifies the ID for the domain
536f11c7f63SJim Harris * object.
537f11c7f63SJim Harris * @param[in] fw_controller This parameter specifies the controller managing
538f11c7f63SJim Harris * the domain being constructed.
539f11c7f63SJim Harris *
540f11c7f63SJim Harris * @return none
541f11c7f63SJim Harris */
scif_sas_domain_construct(SCIF_SAS_DOMAIN_T * fw_domain,U8 domain_id,SCIF_SAS_CONTROLLER_T * fw_controller)542f11c7f63SJim Harris void scif_sas_domain_construct(
543f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain,
544f11c7f63SJim Harris U8 domain_id,
545f11c7f63SJim Harris SCIF_SAS_CONTROLLER_T * fw_controller
546f11c7f63SJim Harris )
547f11c7f63SJim Harris {
548f11c7f63SJim Harris SCIF_LOG_TRACE((
549f11c7f63SJim Harris sci_base_object_get_logger(fw_controller),
550f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_INITIALIZATION,
551f11c7f63SJim Harris "scif_sas_domain_construct(0x%x, 0x%x, 0x%x) enter\n",
552f11c7f63SJim Harris fw_domain, domain_id, fw_controller
553f11c7f63SJim Harris ));
554f11c7f63SJim Harris
555f11c7f63SJim Harris sci_base_domain_construct(
556f11c7f63SJim Harris &fw_domain->parent,
557f11c7f63SJim Harris sci_base_object_get_logger(fw_controller),
558f11c7f63SJim Harris scif_sas_domain_state_table
559f11c7f63SJim Harris );
560f11c7f63SJim Harris
561f11c7f63SJim Harris scif_sas_domain_initialize_state_logging(fw_domain);
562f11c7f63SJim Harris
563f11c7f63SJim Harris sci_abstract_list_construct(
564f11c7f63SJim Harris &fw_domain->remote_device_list, &fw_controller->free_remote_device_pool
565f11c7f63SJim Harris );
566f11c7f63SJim Harris
567f11c7f63SJim Harris // Retrieve the core's port object that directly corresponds to this
568f11c7f63SJim Harris // domain.
569f11c7f63SJim Harris scic_controller_get_port_handle(
570f11c7f63SJim Harris fw_controller->core_object, domain_id, &fw_domain->core_object
571f11c7f63SJim Harris );
572f11c7f63SJim Harris
573f11c7f63SJim Harris // Set the association in the core port to this framework domain object.
574f11c7f63SJim Harris sci_object_set_association(
575f11c7f63SJim Harris (SCI_OBJECT_HANDLE_T) fw_domain->core_object, fw_domain
576f11c7f63SJim Harris );
577f11c7f63SJim Harris
578f11c7f63SJim Harris sci_fast_list_init(&fw_domain->request_list);
579f11c7f63SJim Harris
580f11c7f63SJim Harris fw_domain->operation.timer = NULL;
581f11c7f63SJim Harris
582f11c7f63SJim Harris fw_domain->is_port_ready = FALSE;
583f11c7f63SJim Harris fw_domain->device_start_count = 0;
584f11c7f63SJim Harris fw_domain->controller = fw_controller;
585f11c7f63SJim Harris fw_domain->operation.status = SCI_SUCCESS;
586f11c7f63SJim Harris fw_domain->is_config_route_table_needed = FALSE;
587f11c7f63SJim Harris }
588f11c7f63SJim Harris
589f11c7f63SJim Harris /**
590f11c7f63SJim Harris * @brief This method will terminate the requests outstanding in the core
591f11c7f63SJim Harris * based on the supplied criteria.
592f11c7f63SJim Harris * - if the all three parameters are specified then only the single
593f11c7f63SJim Harris * SCIF_SAS_REQUEST object is terminated.
594f11c7f63SJim Harris * - if only the SCIF_SAS_DOMAIN and SCIF_SAS_REMOTE_DEVICE are
595f11c7f63SJim Harris * specified, then all SCIF_SAS_REQUEST objects outstanding at
596f11c7f63SJim Harris * the device are terminated. The one exclusion to this rule is
597f11c7f63SJim Harris * that the fw_requestor is not terminated.
598f11c7f63SJim Harris * - if only the SCIF_SAS_DOMAIN object is specified, then all
599f11c7f63SJim Harris * SCIF_SAS_REQUEST objects outstanding in the domain are
600f11c7f63SJim Harris * terminated.
601f11c7f63SJim Harris *
602f11c7f63SJim Harris * @param[in] fw_domain This parameter specifies the domain in which to
603f11c7f63SJim Harris * terminate requests.
604f11c7f63SJim Harris * @param[in] fw_device This parameter specifies the remote device in
605f11c7f63SJim Harris * which to terminate requests. This parameter can be NULL
606f11c7f63SJim Harris * as long as the fw_request parameter is NULL. It is a
607f11c7f63SJim Harris * required parameter if the fw_request parameter is not NULL.
608f11c7f63SJim Harris * @param[in] fw_request This parameter specifies the request object to
609f11c7f63SJim Harris * be terminated. This parameter can be NULL.
610f11c7f63SJim Harris * @param[in] fw_requestor This parameter specifies the task management
611f11c7f63SJim Harris * request that is responsible for the termination of requests.
612f11c7f63SJim Harris *
613f11c7f63SJim Harris * @return none
614f11c7f63SJim Harris */
scif_sas_domain_terminate_requests(SCIF_SAS_DOMAIN_T * fw_domain,SCIF_SAS_REMOTE_DEVICE_T * fw_device,SCIF_SAS_REQUEST_T * fw_request,SCIF_SAS_TASK_REQUEST_T * fw_requestor)615f11c7f63SJim Harris void scif_sas_domain_terminate_requests(
616f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain,
617f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * fw_device,
618f11c7f63SJim Harris SCIF_SAS_REQUEST_T * fw_request,
619f11c7f63SJim Harris SCIF_SAS_TASK_REQUEST_T * fw_requestor
620f11c7f63SJim Harris )
621f11c7f63SJim Harris {
622f11c7f63SJim Harris SCIF_LOG_TRACE((
623f11c7f63SJim Harris sci_base_object_get_logger(fw_domain),
624f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
625f11c7f63SJim Harris "scif_sas_domain_terminate_requests(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
626f11c7f63SJim Harris fw_domain, fw_device, fw_request, fw_requestor
627f11c7f63SJim Harris ));
628f11c7f63SJim Harris
629f11c7f63SJim Harris if (fw_request != NULL)
630f11c7f63SJim Harris {
631f11c7f63SJim Harris fw_request->terminate_requestor = fw_requestor;
632f11c7f63SJim Harris fw_request->state_handlers->abort_handler(&fw_request->parent);
633f11c7f63SJim Harris }
634f11c7f63SJim Harris else
635f11c7f63SJim Harris {
636f11c7f63SJim Harris SCI_FAST_LIST_ELEMENT_T * element = fw_domain->request_list.list_head;
637f11c7f63SJim Harris SCIF_SAS_REQUEST_T * request = NULL;
638f11c7f63SJim Harris
639f11c7f63SJim Harris // Cycle through the fast list of IO requests. Terminate each
6407a2b450fSEitan Adler // outstanding requests that matches the criteria supplied by the
641f11c7f63SJim Harris // caller.
642f11c7f63SJim Harris while (element != NULL)
643f11c7f63SJim Harris {
644f11c7f63SJim Harris request = (SCIF_SAS_REQUEST_T*) sci_fast_list_get_object(element);
645453130d9SPedro F. Giffuni // The current element may be deleted from the list because of
646f11c7f63SJim Harris // IO completion so advance to the next element early
647f11c7f63SJim Harris element = sci_fast_list_get_next(element);
648f11c7f63SJim Harris
649f11c7f63SJim Harris // Ensure we pass the supplied criteria before terminating the
650f11c7f63SJim Harris // request.
651f11c7f63SJim Harris if (
652f11c7f63SJim Harris (fw_device == NULL)
653f11c7f63SJim Harris || (
654f11c7f63SJim Harris (request->device == fw_device)
655f11c7f63SJim Harris && (fw_requestor != (SCIF_SAS_TASK_REQUEST_T*) request)
656f11c7f63SJim Harris )
657f11c7f63SJim Harris )
658f11c7f63SJim Harris {
659f11c7f63SJim Harris if (
660f11c7f63SJim Harris (request->is_waiting_for_abort_task_set == FALSE) ||
661f11c7f63SJim Harris (request->terminate_requestor == NULL)
662f11c7f63SJim Harris )
663f11c7f63SJim Harris {
664f11c7f63SJim Harris request->terminate_requestor = fw_requestor;
665f11c7f63SJim Harris request->state_handlers->abort_handler(&request->parent);
666f11c7f63SJim Harris }
667f11c7f63SJim Harris }
668f11c7f63SJim Harris }
669f11c7f63SJim Harris }
670f11c7f63SJim Harris }
671f11c7f63SJim Harris
672f11c7f63SJim Harris /**
673f11c7f63SJim Harris * @brief This method searches the domain object to find a
674f11c7f63SJim Harris * SCIF_SAS_REQUEST object associated with the supplied IO tag.
675f11c7f63SJim Harris *
676f11c7f63SJim Harris * @param[in] fw_domain This parameter specifies the domain in which to
677f11c7f63SJim Harris * to find the request object.
678f11c7f63SJim Harris * @param[in] io_tag This parameter specifies the IO tag value for which
679f11c7f63SJim Harris * to locate the corresponding request.
680f11c7f63SJim Harris *
681f11c7f63SJim Harris * @return This method returns a pointer to the SCIF_SAS_REQUEST object
682f11c7f63SJim Harris * associated with the supplied IO tag.
683f11c7f63SJim Harris * @retval NULL This value is returned if the IO tag does not resolve to
684f11c7f63SJim Harris * a request.
685f11c7f63SJim Harris */
scif_sas_domain_get_request_by_io_tag(SCIF_SAS_DOMAIN_T * fw_domain,U16 io_tag)686f11c7f63SJim Harris SCIF_SAS_REQUEST_T * scif_sas_domain_get_request_by_io_tag(
687f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain,
688f11c7f63SJim Harris U16 io_tag
689f11c7f63SJim Harris )
690f11c7f63SJim Harris {
691f11c7f63SJim Harris SCI_FAST_LIST_ELEMENT_T * element = fw_domain->request_list.list_head;
692f11c7f63SJim Harris SCIF_SAS_IO_REQUEST_T * io_request = NULL;
693f11c7f63SJim Harris
694f11c7f63SJim Harris SCIF_LOG_TRACE((
695f11c7f63SJim Harris sci_base_object_get_logger(fw_domain),
696f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_TASK_MANAGEMENT,
697f11c7f63SJim Harris "scif_sas_domain_get_request_by_io_tag(0x%x, 0x%x) enter\n",
698f11c7f63SJim Harris fw_domain, io_tag
699f11c7f63SJim Harris ));
700f11c7f63SJim Harris
701f11c7f63SJim Harris while (element != NULL)
702f11c7f63SJim Harris {
703f11c7f63SJim Harris io_request = (SCIF_SAS_IO_REQUEST_T*) sci_fast_list_get_object(element);
704f11c7f63SJim Harris
705f11c7f63SJim Harris // Check to see if we located the request with an identical IO tag.
706f11c7f63SJim Harris if (scic_io_request_get_io_tag(io_request->parent.core_object) == io_tag)
707f11c7f63SJim Harris return &io_request->parent;
708f11c7f63SJim Harris
709f11c7f63SJim Harris element = sci_fast_list_get_next(element);
710f11c7f63SJim Harris }
711f11c7f63SJim Harris
712f11c7f63SJim Harris return NULL;
713f11c7f63SJim Harris }
714f11c7f63SJim Harris
715f11c7f63SJim Harris /**
716f11c7f63SJim Harris * @brief This method performs domain object initialization to be done
717f11c7f63SJim Harris * when the scif_controller_initialize() method is invoked.
718f11c7f63SJim Harris * This includes operation timeout creation.
719f11c7f63SJim Harris *
720f11c7f63SJim Harris * @param[in] fw_domain This parameter specifies the domain object for
721f11c7f63SJim Harris * which to perform initialization.
722f11c7f63SJim Harris *
723f11c7f63SJim Harris * @return none
724f11c7f63SJim Harris */
scif_sas_domain_initialize(SCIF_SAS_DOMAIN_T * fw_domain)725f11c7f63SJim Harris void scif_sas_domain_initialize(
726f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain
727f11c7f63SJim Harris )
728f11c7f63SJim Harris {
729f11c7f63SJim Harris SCIF_LOG_TRACE((
730f11c7f63SJim Harris sci_base_object_get_logger(fw_domain),
731f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_INITIALIZATION,
732f11c7f63SJim Harris "scif_sas_domain_initialize(0x%x) enter\n",
733f11c7f63SJim Harris fw_domain
734f11c7f63SJim Harris ));
735f11c7f63SJim Harris
736f11c7f63SJim Harris // Create the timer for each domain. It is too early in the process
737f11c7f63SJim Harris // to allocate this during construction since the user didn't have
738f11c7f63SJim Harris // a chance to set it's association.
739f11c7f63SJim Harris if (fw_domain->operation.timer == 0)
740f11c7f63SJim Harris {
741f11c7f63SJim Harris fw_domain->operation.timer = scif_cb_timer_create(
742f11c7f63SJim Harris fw_domain->controller,
743f11c7f63SJim Harris scif_sas_domain_operation_timeout_handler,
744f11c7f63SJim Harris fw_domain
745f11c7f63SJim Harris );
746f11c7f63SJim Harris }
747f11c7f63SJim Harris }
748f11c7f63SJim Harris
749f11c7f63SJim Harris /**
750f11c7f63SJim Harris * @brief This method performs domain object handling for core remote
751f11c7f63SJim Harris * device start complete notifications. Core remote device starts
752f11c7f63SJim Harris * and start completes are only done during discovery. This could
753f11c7f63SJim Harris * ultimately be wrapped into a handler method on the domain (they
754f11c7f63SJim Harris * actually already exist). This method will decrement the number
755f11c7f63SJim Harris * of device start operations ongoing and attempt to determine if
756f11c7f63SJim Harris * discovery is complete.
757f11c7f63SJim Harris *
758f11c7f63SJim Harris * @param[in] fw_domain This parameter specifies the domain object for
759f11c7f63SJim Harris * which to perform initialization.
760f11c7f63SJim Harris *
761f11c7f63SJim Harris * @return none
762f11c7f63SJim Harris */
scif_sas_domain_remote_device_start_complete(SCIF_SAS_DOMAIN_T * fw_domain,SCIF_SAS_REMOTE_DEVICE_T * fw_device)763f11c7f63SJim Harris void scif_sas_domain_remote_device_start_complete(
764f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain,
765f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * fw_device
766f11c7f63SJim Harris )
767f11c7f63SJim Harris {
768f11c7f63SJim Harris SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols;
769f11c7f63SJim Harris
770f11c7f63SJim Harris SCIF_LOG_TRACE((
771f11c7f63SJim Harris sci_base_object_get_logger(fw_domain),
772f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
773f11c7f63SJim Harris "scif_sas_domain_remote_device_start_complete(0x%x, 0x%x) enter\n",
774f11c7f63SJim Harris fw_domain, fw_device
775f11c7f63SJim Harris ));
776f11c7f63SJim Harris
777f11c7f63SJim Harris // If a device is being started/start completed, then we must be
778f11c7f63SJim Harris // during discovery.
779f11c7f63SJim Harris ASSERT(fw_domain->parent.state_machine.current_state_id
780f11c7f63SJim Harris == SCI_BASE_DOMAIN_STATE_DISCOVERING);
781f11c7f63SJim Harris
782f11c7f63SJim Harris scic_remote_device_get_protocols(fw_device->core_object, &dev_protocols);
783f11c7f63SJim Harris
784f11c7f63SJim Harris // Decrement the number of devices being started and check to see
785f11c7f63SJim Harris // if all have finished being started or failed as the case may be.
786f11c7f63SJim Harris fw_domain->device_start_in_progress_count--;
787f11c7f63SJim Harris
788f11c7f63SJim Harris if ( dev_protocols.u.bits.attached_smp_target )
789f11c7f63SJim Harris {
790f11c7f63SJim Harris if ( fw_device->containing_device == NULL )
791f11c7f63SJim Harris //kick off the smp discover process if this expander is direct attached.
792f11c7f63SJim Harris scif_sas_smp_remote_device_start_discover(fw_device);
793f11c7f63SJim Harris else
794f11c7f63SJim Harris //mark this device, the discover process of this device will start after
795f11c7f63SJim Harris //its containing smp device finish discover.
796f11c7f63SJim Harris fw_device->protocol_device.smp_device.scheduled_activity =
797f11c7f63SJim Harris SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_DISCOVER;
798f11c7f63SJim Harris }
799f11c7f63SJim Harris else
800f11c7f63SJim Harris {
801f11c7f63SJim Harris fw_domain->state_handlers->device_start_complete_handler(
802f11c7f63SJim Harris &fw_domain->parent, &fw_device->parent
803f11c7f63SJim Harris );
804f11c7f63SJim Harris }
805f11c7f63SJim Harris }
806f11c7f63SJim Harris
807f11c7f63SJim Harris
808f11c7f63SJim Harris /**
809f11c7f63SJim Harris * @brief This methods check each smp device in this domain. If there is at
810f11c7f63SJim Harris * least one smp device in discover or target reset activity, this
811f11c7f63SJim Harris * domain is considered in smp activity. Note this routine is not
812f11c7f63SJim Harris * called on fast IO path.
813f11c7f63SJim Harris *
814f11c7f63SJim Harris * @param[in] fw_domain The framework domain object
815f11c7f63SJim Harris *
816f11c7f63SJim Harris * @return BOOL value to indicate whether a domain is in SMP activity.
817f11c7f63SJim Harris */
scif_sas_domain_is_in_smp_activity(SCIF_SAS_DOMAIN_T * fw_domain)818f11c7f63SJim Harris BOOL scif_sas_domain_is_in_smp_activity(
819f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain
820f11c7f63SJim Harris )
821f11c7f63SJim Harris {
822f11c7f63SJim Harris SCI_ABSTRACT_ELEMENT_T * current_element =
823f11c7f63SJim Harris sci_abstract_list_get_front(&fw_domain->remote_device_list);
824f11c7f63SJim Harris
825f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * current_device;
826f11c7f63SJim Harris
827f11c7f63SJim Harris while ( current_element != NULL )
828f11c7f63SJim Harris {
829f11c7f63SJim Harris SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols;
830f11c7f63SJim Harris
831f11c7f63SJim Harris current_device = (SCIF_SAS_REMOTE_DEVICE_T *)
832f11c7f63SJim Harris sci_abstract_list_get_object(current_element);
833f11c7f63SJim Harris
834f11c7f63SJim Harris scic_remote_device_get_protocols(current_device->core_object,
835f11c7f63SJim Harris &dev_protocols
836f11c7f63SJim Harris );
837f11c7f63SJim Harris
838f11c7f63SJim Harris if (dev_protocols.u.bits.attached_smp_target &&
839f11c7f63SJim Harris scif_sas_smp_remote_device_is_in_activity(current_device))
840f11c7f63SJim Harris return TRUE;
841f11c7f63SJim Harris
842f11c7f63SJim Harris current_element =
843f11c7f63SJim Harris sci_abstract_list_get_next(current_element);
844f11c7f63SJim Harris }
845f11c7f63SJim Harris
846f11c7f63SJim Harris return FALSE;
847f11c7f63SJim Harris }
848f11c7f63SJim Harris
849f11c7f63SJim Harris
850f11c7f63SJim Harris /**
851f11c7f63SJim Harris * @brief This methods finds a expander attached device by searching the domain's
852f11c7f63SJim Harris * device list using connected expander device and expander phy id.
853f11c7f63SJim Harris *
854f11c7f63SJim Harris * @param[in] fw_domain The framework domain object
855f11c7f63SJim Harris * @param[in] parent_device The expander device the target device attaches to.
856f11c7f63SJim Harris * @param[in] expander_phy_id The expander phy id that the target device owns.
857f11c7f63SJim Harris *
858f11c7f63SJim Harris * @return found remote device or a NULL value if no device found.
859f11c7f63SJim Harris */
scif_sas_domain_get_device_by_containing_device(SCIF_SAS_DOMAIN_T * fw_domain,SCIF_SAS_REMOTE_DEVICE_T * containing_device,U8 expander_phy_id)860f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * scif_sas_domain_get_device_by_containing_device(
861f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain,
862f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * containing_device,
863f11c7f63SJim Harris U8 expander_phy_id
864f11c7f63SJim Harris )
865f11c7f63SJim Harris {
866f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * fw_device;
867f11c7f63SJim Harris SCI_ABSTRACT_ELEMENT_T * element = sci_abstract_list_get_front(
868f11c7f63SJim Harris &fw_domain->remote_device_list
869f11c7f63SJim Harris );
870f11c7f63SJim Harris
871f11c7f63SJim Harris //parent device must not be NULL.
872f11c7f63SJim Harris ASSERT(containing_device != NULL);
873f11c7f63SJim Harris
874f11c7f63SJim Harris // Search the abstract list to see if there is a remote device meets the
875f11c7f63SJim Harris // search condition.
876f11c7f63SJim Harris while (element != NULL)
877f11c7f63SJim Harris {
878f11c7f63SJim Harris fw_device = (SCIF_SAS_REMOTE_DEVICE_T*)
879f11c7f63SJim Harris sci_abstract_list_get_object(element);
880f11c7f63SJim Harris
881f11c7f63SJim Harris // Check to see if this is the device for which we are searching.
882f11c7f63SJim Harris if (
883f11c7f63SJim Harris (fw_device->containing_device == containing_device)
884f11c7f63SJim Harris && (fw_device->expander_phy_identifier == expander_phy_id)
885f11c7f63SJim Harris )
886f11c7f63SJim Harris {
887f11c7f63SJim Harris return fw_device;
888f11c7f63SJim Harris }
889f11c7f63SJim Harris
890f11c7f63SJim Harris element = sci_abstract_list_get_next(element);
891f11c7f63SJim Harris }
892f11c7f63SJim Harris
893f11c7f63SJim Harris return SCI_INVALID_HANDLE;
894f11c7f63SJim Harris }
895f11c7f63SJim Harris
896f11c7f63SJim Harris
897f11c7f63SJim Harris /**
898f11c7f63SJim Harris * @brief This methods finds the first device that is in STOPPED state and its
899f11c7f63SJim Harris * connection_rate is still in SPINUP_HOLD(value 3).
900f11c7f63SJim Harris *
901f11c7f63SJim Harris * @param[in] fw_domain The framework domain object
902f11c7f63SJim Harris *
903f11c7f63SJim Harris * @return SCIF_SAS_REMOTE_DEVICE_T The device that is in SPINUP_HOLD or NULL.
904f11c7f63SJim Harris */
scif_sas_domain_find_device_in_spinup_hold(SCIF_SAS_DOMAIN_T * fw_domain)905f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * scif_sas_domain_find_device_in_spinup_hold(
906f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain
907f11c7f63SJim Harris )
908f11c7f63SJim Harris {
909f11c7f63SJim Harris SCI_ABSTRACT_ELEMENT_T * current_element;
910f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * current_device;
911f11c7f63SJim Harris
912f11c7f63SJim Harris SCIF_LOG_TRACE((
913f11c7f63SJim Harris sci_base_object_get_logger(fw_domain),
914f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN,
915f11c7f63SJim Harris "scif_sas_domain_find_device_in_spinup_hold(0x%x) enter\n",
916f11c7f63SJim Harris fw_domain
917f11c7f63SJim Harris ));
918f11c7f63SJim Harris
919f11c7f63SJim Harris //search throught domain's device list to find the first sata device on spinup_hold
920f11c7f63SJim Harris current_element = sci_abstract_list_get_front(&fw_domain->remote_device_list);
921f11c7f63SJim Harris while (current_element != NULL )
922f11c7f63SJim Harris {
923f11c7f63SJim Harris current_device = (SCIF_SAS_REMOTE_DEVICE_T *)
924f11c7f63SJim Harris sci_abstract_list_get_object(current_element);
925f11c7f63SJim Harris
926f11c7f63SJim Harris //We must get the next element before we remove the current
927f11c7f63SJim Harris //device. Or else, we will get wrong next_element, since the erased
928f11c7f63SJim Harris //element has been put into free pool.
929f11c7f63SJim Harris current_element = sci_abstract_list_get_next(current_element);
930f11c7f63SJim Harris
931f11c7f63SJim Harris if ( sci_base_state_machine_get_state(¤t_device->parent.state_machine) ==
932f11c7f63SJim Harris SCI_BASE_REMOTE_DEVICE_STATE_STOPPED
933f11c7f63SJim Harris && scic_remote_device_get_connection_rate(current_device->core_object) ==
934f11c7f63SJim Harris SCI_SATA_SPINUP_HOLD )
935f11c7f63SJim Harris {
936f11c7f63SJim Harris return current_device;
937f11c7f63SJim Harris }
938f11c7f63SJim Harris }
939f11c7f63SJim Harris
940f11c7f63SJim Harris return NULL;
941f11c7f63SJim Harris }
942f11c7f63SJim Harris
943f11c7f63SJim Harris
944f11c7f63SJim Harris /**
945f11c7f63SJim Harris * @brief This methods finds the first device that has specific activity scheduled.
946f11c7f63SJim Harris *
947f11c7f63SJim Harris * @param[in] fw_domain The framework domain object
948f11c7f63SJim Harris * @param[in] smp_activity A specified smp activity. The valid range is [1,5].
949f11c7f63SJim Harris *
950f11c7f63SJim Harris * @return SCIF_SAS_REMOTE_DEVICE_T The device that has specified smp activity scheduled.
951f11c7f63SJim Harris */
scif_sas_domain_find_device_has_scheduled_activity(SCIF_SAS_DOMAIN_T * fw_domain,U8 smp_activity)952f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * scif_sas_domain_find_device_has_scheduled_activity(
953f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain,
954f11c7f63SJim Harris U8 smp_activity
955f11c7f63SJim Harris )
956f11c7f63SJim Harris {
957f11c7f63SJim Harris SCI_ABSTRACT_ELEMENT_T * current_element =
958f11c7f63SJim Harris sci_abstract_list_get_front(&fw_domain->remote_device_list);
959f11c7f63SJim Harris
960f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * current_device;
961f11c7f63SJim Harris SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols;
962f11c7f63SJim Harris
963f11c7f63SJim Harris //config route table activity has higher priority than discover activity.
964f11c7f63SJim Harris while ( current_element != NULL )
965f11c7f63SJim Harris {
966f11c7f63SJim Harris current_device = (SCIF_SAS_REMOTE_DEVICE_T *)
967f11c7f63SJim Harris sci_abstract_list_get_object(current_element);
968f11c7f63SJim Harris
969f11c7f63SJim Harris scic_remote_device_get_protocols(current_device->core_object,
970f11c7f63SJim Harris &dev_protocols);
971f11c7f63SJim Harris
972f11c7f63SJim Harris current_element =
973f11c7f63SJim Harris sci_abstract_list_get_next(current_element);
974f11c7f63SJim Harris
975f11c7f63SJim Harris if ( dev_protocols.u.bits.attached_smp_target
976f11c7f63SJim Harris && current_device->protocol_device.smp_device.scheduled_activity ==
977f11c7f63SJim Harris smp_activity)
978f11c7f63SJim Harris {
979f11c7f63SJim Harris return current_device;
980f11c7f63SJim Harris }
981f11c7f63SJim Harris }
982f11c7f63SJim Harris
983f11c7f63SJim Harris return NULL;
984f11c7f63SJim Harris }
985f11c7f63SJim Harris
986f11c7f63SJim Harris
987f11c7f63SJim Harris /**
988f11c7f63SJim Harris * @brief This methods finds the smp device that has is_config_route_table_scheduled
989f11c7f63SJim Harris * flag set to TRUE, and start config route table on it. If there is no
990f11c7f63SJim Harris * smp device scheduled to config route table, find the smp device has
991f11c7f63SJim Harris * is_discover_scheduled and start the smp discover process on them.
992f11c7f63SJim Harris *
993f11c7f63SJim Harris * @param[in] fw_domain The framework domain that to start smp discover process.
994f11c7f63SJim Harris *
995f11c7f63SJim Harris * @return NONE
996f11c7f63SJim Harris */
scif_sas_domain_start_smp_activity(SCIF_SAS_DOMAIN_T * fw_domain)997f11c7f63SJim Harris void scif_sas_domain_start_smp_activity(
998f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain
999f11c7f63SJim Harris )
1000f11c7f63SJim Harris {
1001f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * device_has_scheduled_activity = NULL;
1002f11c7f63SJim Harris
1003f11c7f63SJim Harris //first, find device that has config route table activity scheduled.
1004f11c7f63SJim Harris //config route table activity has higher priority than Discover.
1005f11c7f63SJim Harris device_has_scheduled_activity =
1006f11c7f63SJim Harris scif_sas_domain_find_device_has_scheduled_activity(
1007f11c7f63SJim Harris fw_domain,
1008f11c7f63SJim Harris SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_CONFIG_ROUTE_TABLE
1009f11c7f63SJim Harris );
1010f11c7f63SJim Harris
1011f11c7f63SJim Harris if (device_has_scheduled_activity != NULL)
1012f11c7f63SJim Harris {
1013f11c7f63SJim Harris scif_sas_smp_remote_device_configure_route_table(device_has_scheduled_activity);
1014f11c7f63SJim Harris device_has_scheduled_activity->protocol_device.smp_device.scheduled_activity =
1015f11c7f63SJim Harris SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_NONE;
1016f11c7f63SJim Harris return;
1017f11c7f63SJim Harris }
1018f11c7f63SJim Harris
1019f11c7f63SJim Harris //if no device has config route table activity scheduled, search again, find
1020f11c7f63SJim Harris //device has discover activity scheduled.
1021f11c7f63SJim Harris device_has_scheduled_activity =
1022f11c7f63SJim Harris scif_sas_domain_find_device_has_scheduled_activity(
1023f11c7f63SJim Harris fw_domain,
1024f11c7f63SJim Harris SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_DISCOVER
1025f11c7f63SJim Harris );
1026f11c7f63SJim Harris
1027f11c7f63SJim Harris if (device_has_scheduled_activity != NULL)
1028f11c7f63SJim Harris scif_sas_smp_remote_device_start_discover(device_has_scheduled_activity);
1029f11c7f63SJim Harris }
1030f11c7f63SJim Harris
1031f11c7f63SJim Harris
1032f11c7f63SJim Harris /**
1033f11c7f63SJim Harris * @brief This method starts domain's smp discover process from the top level expander.
1034f11c7f63SJim Harris *
1035f11c7f63SJim Harris * @param[in] fw_domain The framework domain that to start smp discover process.
1036f11c7f63SJim Harris @ @param[in] top_expander The top level expander device to start smp discover process.
1037f11c7f63SJim Harris *
1038f11c7f63SJim Harris * @return None
1039f11c7f63SJim Harris */
scif_sas_domain_start_smp_discover(SCIF_SAS_DOMAIN_T * fw_domain,SCIF_SAS_REMOTE_DEVICE_T * top_expander)1040f11c7f63SJim Harris void scif_sas_domain_start_smp_discover(
1041f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain,
1042f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * top_expander
1043f11c7f63SJim Harris )
1044f11c7f63SJim Harris {
1045f11c7f63SJim Harris SCI_ABSTRACT_ELEMENT_T * current_element =
1046f11c7f63SJim Harris sci_abstract_list_get_front(&fw_domain->remote_device_list);
1047f11c7f63SJim Harris
1048f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * current_device;
1049f11c7f63SJim Harris
1050f11c7f63SJim Harris // something changed behind expander
1051f11c7f63SJim Harris // mark all the device behind expander to be NOT
1052f11c7f63SJim Harris // is_currently_discovered.
1053f11c7f63SJim Harris while ( current_element != NULL )
1054f11c7f63SJim Harris {
1055f11c7f63SJim Harris current_device = (SCIF_SAS_REMOTE_DEVICE_T *)
1056f11c7f63SJim Harris sci_abstract_list_get_object(current_element);
1057f11c7f63SJim Harris
1058f11c7f63SJim Harris current_device->is_currently_discovered = FALSE;
1059f11c7f63SJim Harris
1060f11c7f63SJim Harris //reset all the devices' port witdh except the top expander.
1061f11c7f63SJim Harris if (current_device->containing_device != NULL)
1062f11c7f63SJim Harris current_device->device_port_width = 1;
1063f11c7f63SJim Harris
1064f11c7f63SJim Harris current_element = sci_abstract_list_get_next(current_element);
1065f11c7f63SJim Harris }
1066f11c7f63SJim Harris
1067f11c7f63SJim Harris //expander device itself should be set to is_currently_discovered.
1068f11c7f63SJim Harris top_expander->is_currently_discovered = TRUE;
1069f11c7f63SJim Harris
1070f11c7f63SJim Harris //kick off the smp discover process.
1071f11c7f63SJim Harris scif_sas_smp_remote_device_start_discover(top_expander);
1072f11c7f63SJim Harris }
1073f11c7f63SJim Harris
1074f11c7f63SJim Harris
1075f11c7f63SJim Harris /**
1076f11c7f63SJim Harris * @brief This method continues domain's smp discover process and
1077f11c7f63SJim Harris * may transit to READY state if all smp activities are done.
1078f11c7f63SJim Harris *
1079f11c7f63SJim Harris * @param[in] fw_domain The framework domain that to start smp discover process.
1080f11c7f63SJim Harris *
1081f11c7f63SJim Harris * @return None
1082f11c7f63SJim Harris */
scif_sas_domain_continue_discover(SCIF_SAS_DOMAIN_T * fw_domain)1083f11c7f63SJim Harris void scif_sas_domain_continue_discover(
1084f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain
1085f11c7f63SJim Harris )
1086f11c7f63SJim Harris {
1087f11c7f63SJim Harris SCIF_LOG_TRACE((
1088f11c7f63SJim Harris sci_base_object_get_logger(fw_domain),
1089f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
1090f11c7f63SJim Harris "scif_sas_domain_continue_discover(0x%x) enter\n",
1091f11c7f63SJim Harris fw_domain
1092f11c7f63SJim Harris ));
1093f11c7f63SJim Harris
1094f11c7f63SJim Harris if ( fw_domain->device_start_in_progress_count == 0
1095f11c7f63SJim Harris && !scif_sas_domain_is_in_smp_activity(fw_domain) )
1096f11c7f63SJim Harris {
1097f11c7f63SJim Harris //domain scrub the remote device list to see if there is a need
1098f11c7f63SJim Harris //to start smp discover on expander device. There may be no
1099f11c7f63SJim Harris //need to start any smp discover.
1100f11c7f63SJim Harris scif_sas_domain_start_smp_activity(fw_domain);
1101f11c7f63SJim Harris
1102f11c7f63SJim Harris //In domain discovery timeout case, we cancel all
1103f11c7f63SJim Harris //the smp activities, and terminate all the smp requests, then
1104f11c7f63SJim Harris //this routine is called. But the smp request may not done
1105f11c7f63SJim Harris //terminated. We want to guard the domain trasitting to READY
1106f11c7f63SJim Harris //by checking outstanding smp request count. If there is outstanding
1107f11c7f63SJim Harris //smp request, the domain will not transit to READY. Later when
1108f11c7f63SJim Harris //the smp request is terminated at smp remote device, this routine
1109f11c7f63SJim Harris //will be called then the domain will transit to READY state.
1110f11c7f63SJim Harris if ( ! scif_sas_domain_is_in_smp_activity(fw_domain)
1111f11c7f63SJim Harris && scif_sas_domain_get_smp_request_count(fw_domain) == 0)
1112f11c7f63SJim Harris {
1113f11c7f63SJim Harris //before domain transit to READY state, domain has some clean up
1114f11c7f63SJim Harris //work to do, such like update domain's remote devcie list.
1115f11c7f63SJim Harris scif_sas_domain_finish_discover(fw_domain);
1116f11c7f63SJim Harris }
1117f11c7f63SJim Harris }
1118f11c7f63SJim Harris }
1119f11c7f63SJim Harris
1120f11c7f63SJim Harris
1121f11c7f63SJim Harris /**
1122f11c7f63SJim Harris * @brief This method finishes domain's smp discover process and
1123f11c7f63SJim Harris * update domain's remote device list.
1124f11c7f63SJim Harris *
1125f11c7f63SJim Harris * @param[in] fw_domain The framework domain that's to finish smp discover process.
1126f11c7f63SJim Harris *
1127f11c7f63SJim Harris * @return None
1128f11c7f63SJim Harris */
scif_sas_domain_finish_discover(SCIF_SAS_DOMAIN_T * fw_domain)1129f11c7f63SJim Harris void scif_sas_domain_finish_discover(
1130f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain
1131f11c7f63SJim Harris )
1132f11c7f63SJim Harris {
1133f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * current_device = NULL;
1134f11c7f63SJim Harris SCI_ABSTRACT_ELEMENT_T * current_element = NULL;
1135f11c7f63SJim Harris
1136f11c7f63SJim Harris SCIF_LOG_TRACE((
1137f11c7f63SJim Harris sci_base_object_get_logger(fw_domain),
1138f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
1139f11c7f63SJim Harris "scif_sas_domain_finish_discover(0x%x) enter\n",
1140f11c7f63SJim Harris fw_domain
1141f11c7f63SJim Harris ));
1142f11c7f63SJim Harris
1143f11c7f63SJim Harris //need to scrub all the devices behind the expander. Check each
1144f11c7f63SJim Harris //device's discover_status. if the is_currently_discovered is FALSE, means
1145f11c7f63SJim Harris //the device is not been rediscovered. this device needs to be removed.
1146f11c7f63SJim Harris current_element = sci_abstract_list_get_front(&fw_domain->remote_device_list);
1147f11c7f63SJim Harris while (current_element != NULL )
1148f11c7f63SJim Harris {
1149f11c7f63SJim Harris current_device = (SCIF_SAS_REMOTE_DEVICE_T *)
1150f11c7f63SJim Harris sci_abstract_list_get_object(current_element);
1151f11c7f63SJim Harris
1152f11c7f63SJim Harris //We must get the next element before we remove the current
1153f11c7f63SJim Harris //device. Or else, we will get wrong next_element, since the erased
1154f11c7f63SJim Harris //element has been put into free pool.
1155f11c7f63SJim Harris current_element = sci_abstract_list_get_next(current_element);
1156f11c7f63SJim Harris
1157f11c7f63SJim Harris if ( current_device->is_currently_discovered == FALSE )
1158f11c7f63SJim Harris {
1159f11c7f63SJim Harris // Notify the framework user of the device removal.
1160f11c7f63SJim Harris scif_cb_domain_device_removed(
1161f11c7f63SJim Harris fw_domain->controller, fw_domain, current_device
1162f11c7f63SJim Harris );
1163f11c7f63SJim Harris }
1164f11c7f63SJim Harris }
1165f11c7f63SJim Harris
1166f11c7f63SJim Harris sci_base_state_machine_change_state(
1167f11c7f63SJim Harris &fw_domain->parent.state_machine, SCI_BASE_DOMAIN_STATE_READY
1168f11c7f63SJim Harris );
1169f11c7f63SJim Harris }
1170f11c7f63SJim Harris
1171f11c7f63SJim Harris
1172f11c7f63SJim Harris
1173f11c7f63SJim Harris /**
1174f11c7f63SJim Harris * @brief This method remove an expander device and its child devices, in order to
1175f11c7f63SJim Harris * deal with a detected illeagal phy connection.
1176f11c7f63SJim Harris *
1177f11c7f63SJim Harris * @param[in] fw_domain The domain that a expander belongs to.
1178f11c7f63SJim Harris * @param[in] fw_device The expander device to be removed.
1179f11c7f63SJim Harris *
1180f11c7f63SJim Harris * @return none.
1181f11c7f63SJim Harris */
scif_sas_domain_remove_expander_device(SCIF_SAS_DOMAIN_T * fw_domain,SCIF_SAS_REMOTE_DEVICE_T * fw_device)1182f11c7f63SJim Harris void scif_sas_domain_remove_expander_device(
1183f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain,
1184f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * fw_device
1185f11c7f63SJim Harris )
1186f11c7f63SJim Harris {
1187f11c7f63SJim Harris SCIF_SAS_SMP_REMOTE_DEVICE_T * smp_remote_device =
1188f11c7f63SJim Harris &fw_device->protocol_device.smp_device;
1189f11c7f63SJim Harris
1190f11c7f63SJim Harris SCI_FAST_LIST_ELEMENT_T * element = smp_remote_device->smp_phy_list.list_head;
1191f11c7f63SJim Harris SCIF_SAS_SMP_PHY_T * curr_smp_phy = NULL;
1192f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * current_device = NULL;
1193f11c7f63SJim Harris
1194f11c7f63SJim Harris while (element != NULL)
1195f11c7f63SJim Harris {
1196f11c7f63SJim Harris curr_smp_phy = (SCIF_SAS_SMP_PHY_T*) sci_fast_list_get_object(element);
1197f11c7f63SJim Harris element = sci_fast_list_get_next(element);
1198f11c7f63SJim Harris
1199f11c7f63SJim Harris if ( curr_smp_phy->attached_device_type != SMP_NO_DEVICE_ATTACHED
1200f11c7f63SJim Harris && curr_smp_phy->u.end_device != NULL )
1201f11c7f63SJim Harris {
1202f11c7f63SJim Harris if (curr_smp_phy->attached_device_type == SMP_END_DEVICE_ONLY)
1203f11c7f63SJim Harris current_device = curr_smp_phy->u.end_device;
1204f11c7f63SJim Harris else
1205f11c7f63SJim Harris current_device = curr_smp_phy->u.attached_phy->owning_device;
1206f11c7f63SJim Harris
1207f11c7f63SJim Harris scif_cb_domain_device_removed(fw_domain->controller, fw_domain, current_device);
1208f11c7f63SJim Harris }
1209f11c7f63SJim Harris }
1210f11c7f63SJim Harris
1211f11c7f63SJim Harris //remove device itself
1212f11c7f63SJim Harris scif_cb_domain_device_removed(fw_domain->controller, fw_domain, fw_device);
1213f11c7f63SJim Harris }
1214f11c7f63SJim Harris
1215f11c7f63SJim Harris
1216f11c7f63SJim Harris /**
1217f11c7f63SJim Harris * @brief This method searches the whole domain and finds all the smp devices to
1218f11c7f63SJim Harris * cancel their smp activities if there is any.
1219f11c7f63SJim Harris *
1220f11c7f63SJim Harris * @param[in] fw_domain The domain that its smp activities are to be canceled.
1221f11c7f63SJim Harris *
1222f11c7f63SJim Harris * @return none.
1223f11c7f63SJim Harris */
scif_sas_domain_cancel_smp_activities(SCIF_SAS_DOMAIN_T * fw_domain)1224f11c7f63SJim Harris void scif_sas_domain_cancel_smp_activities(
1225f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain
1226f11c7f63SJim Harris )
1227f11c7f63SJim Harris {
1228f11c7f63SJim Harris SCI_ABSTRACT_ELEMENT_T * current_element =
1229f11c7f63SJim Harris sci_abstract_list_get_front(&fw_domain->remote_device_list);
1230f11c7f63SJim Harris
1231f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * current_device;
1232f11c7f63SJim Harris
1233f11c7f63SJim Harris //purge all the outstanding internal IOs in HPQ.
1234f11c7f63SJim Harris scif_sas_high_priority_request_queue_purge_domain(
1235f11c7f63SJim Harris &fw_domain->controller->hprq, fw_domain
1236f11c7f63SJim Harris );
1237f11c7f63SJim Harris
1238f11c7f63SJim Harris while ( current_element != NULL )
1239f11c7f63SJim Harris {
1240f11c7f63SJim Harris SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols;
1241f11c7f63SJim Harris
1242f11c7f63SJim Harris current_device = (SCIF_SAS_REMOTE_DEVICE_T *)
1243f11c7f63SJim Harris sci_abstract_list_get_object(current_element);
1244f11c7f63SJim Harris
1245f11c7f63SJim Harris scic_remote_device_get_protocols(current_device->core_object,
1246f11c7f63SJim Harris &dev_protocols
1247f11c7f63SJim Harris );
1248f11c7f63SJim Harris
1249f11c7f63SJim Harris if (dev_protocols.u.bits.attached_smp_target)
1250f11c7f63SJim Harris {
1251f11c7f63SJim Harris scif_sas_smp_remote_device_cancel_smp_activity(current_device);
1252f11c7f63SJim Harris }
1253f11c7f63SJim Harris
1254f11c7f63SJim Harris current_element =
1255f11c7f63SJim Harris sci_abstract_list_get_next(current_element);
1256f11c7f63SJim Harris }
1257f11c7f63SJim Harris }
1258f11c7f63SJim Harris
1259f11c7f63SJim Harris
1260f11c7f63SJim Harris /**
1261f11c7f63SJim Harris * @brief This method searches the domain's request list and counts outstanding
1262f11c7f63SJim Harris * smp IOs.
1263f11c7f63SJim Harris *
1264f11c7f63SJim Harris * @param[in] fw_domain The domain that its request list is to be searched.
1265f11c7f63SJim Harris *
1266f11c7f63SJim Harris * @return U8 The possible return value of this routine is 0 or 1.
1267f11c7f63SJim Harris */
scif_sas_domain_get_smp_request_count(SCIF_SAS_DOMAIN_T * fw_domain)1268f11c7f63SJim Harris U8 scif_sas_domain_get_smp_request_count(
1269f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain
1270f11c7f63SJim Harris )
1271f11c7f63SJim Harris {
1272f11c7f63SJim Harris SCI_FAST_LIST_ELEMENT_T * element = fw_domain->request_list.list_head;
1273f11c7f63SJim Harris SCIF_SAS_REQUEST_T * request = NULL;
1274f11c7f63SJim Harris U8 count = 0;
1275f11c7f63SJim Harris SCIC_TRANSPORT_PROTOCOL protocol;
1276f11c7f63SJim Harris
1277f11c7f63SJim Harris // Cycle through the fast list of IO requests. Terminate each
12787a2b450fSEitan Adler // outstanding requests that matches the criteria supplied by the
1279f11c7f63SJim Harris // caller.
1280f11c7f63SJim Harris while (element != NULL)
1281f11c7f63SJim Harris {
1282f11c7f63SJim Harris request = (SCIF_SAS_REQUEST_T*) sci_fast_list_get_object(element);
1283453130d9SPedro F. Giffuni // The current element may be deleted from the list because of
1284f11c7f63SJim Harris // IO completion so advance to the next element early
1285f11c7f63SJim Harris element = sci_fast_list_get_next(element);
1286f11c7f63SJim Harris
1287f11c7f63SJim Harris protocol = scic_io_request_get_protocol(request->core_object);
1288f11c7f63SJim Harris
1289f11c7f63SJim Harris if ( protocol == SCIC_SMP_PROTOCOL)
1290f11c7f63SJim Harris count++;
1291f11c7f63SJim Harris }
1292f11c7f63SJim Harris
1293f11c7f63SJim Harris return count;
1294f11c7f63SJim Harris }
1295f11c7f63SJim Harris
1296f11c7f63SJim Harris
1297f11c7f63SJim Harris /**
1298f11c7f63SJim Harris * @brief This method start clear affiliation activities for smp devices in
1299f11c7f63SJim Harris * this domain.
1300f11c7f63SJim Harris *
1301f11c7f63SJim Harris * @param[in] fw_domain The domain that its smp devices are scheduled to clear
1302f11c7f63SJim Harris * affiliation for all the EA SATA devices.
1303f11c7f63SJim Harris *
1304f11c7f63SJim Harris * @return none.
1305f11c7f63SJim Harris */
scif_sas_domain_start_clear_affiliation(SCIF_SAS_DOMAIN_T * fw_domain)1306f11c7f63SJim Harris void scif_sas_domain_start_clear_affiliation(
1307f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain
1308f11c7f63SJim Harris )
1309f11c7f63SJim Harris {
1310f11c7f63SJim Harris scif_sas_domain_schedule_clear_affiliation(fw_domain);
1311f11c7f63SJim Harris scif_sas_domain_continue_clear_affiliation(fw_domain);
1312f11c7f63SJim Harris }
1313f11c7f63SJim Harris
1314f11c7f63SJim Harris
1315f11c7f63SJim Harris /**
1316f11c7f63SJim Harris * @brief This method schedule clear affiliation activities for smp devices in
1317f11c7f63SJim Harris * this domain.
1318f11c7f63SJim Harris *
1319f11c7f63SJim Harris * @param[in] fw_domain The domain that its smp devices are scheduled to clear
1320f11c7f63SJim Harris * affiliation for all the EA SATA devices.
1321f11c7f63SJim Harris *
1322f11c7f63SJim Harris * @return none.
1323f11c7f63SJim Harris */
scif_sas_domain_schedule_clear_affiliation(SCIF_SAS_DOMAIN_T * fw_domain)1324f11c7f63SJim Harris void scif_sas_domain_schedule_clear_affiliation(
1325f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain
1326f11c7f63SJim Harris )
1327f11c7f63SJim Harris {
1328f11c7f63SJim Harris SCI_ABSTRACT_ELEMENT_T * current_element =
1329f11c7f63SJim Harris sci_abstract_list_get_front(&fw_domain->remote_device_list);
1330f11c7f63SJim Harris
1331f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * current_device;
1332f11c7f63SJim Harris SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols;
1333f11c7f63SJim Harris
1334f11c7f63SJim Harris //config route table activity has higher priority than discover activity.
1335f11c7f63SJim Harris while ( current_element != NULL )
1336f11c7f63SJim Harris {
1337f11c7f63SJim Harris current_device = (SCIF_SAS_REMOTE_DEVICE_T *)
1338f11c7f63SJim Harris sci_abstract_list_get_object(current_element);
1339f11c7f63SJim Harris
1340f11c7f63SJim Harris scic_remote_device_get_protocols(current_device->core_object,
1341f11c7f63SJim Harris &dev_protocols);
1342f11c7f63SJim Harris
1343f11c7f63SJim Harris current_element =
1344f11c7f63SJim Harris sci_abstract_list_get_next(current_element);
1345f11c7f63SJim Harris
1346f11c7f63SJim Harris if ( dev_protocols.u.bits.attached_smp_target )
1347f11c7f63SJim Harris {
1348f11c7f63SJim Harris current_device->protocol_device.smp_device.scheduled_activity =
1349f11c7f63SJim Harris SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_CLEAR_AFFILIATION;
1350f11c7f63SJim Harris }
1351f11c7f63SJim Harris }
1352f11c7f63SJim Harris }
1353f11c7f63SJim Harris
1354f11c7f63SJim Harris
1355f11c7f63SJim Harris /**
1356f11c7f63SJim Harris * @brief This method carries clear affiliation activities for a smp devices in
1357f11c7f63SJim Harris * this domain during controller stop process.
1358f11c7f63SJim Harris *
1359f11c7f63SJim Harris * @param[in] fw_domain The domain that its smp devices are to clear
1360f11c7f63SJim Harris * affiliation for all the EA SATA devices.
1361f11c7f63SJim Harris *
1362f11c7f63SJim Harris * @return none.
1363f11c7f63SJim Harris */
scif_sas_domain_continue_clear_affiliation(SCIF_SAS_DOMAIN_T * fw_domain)1364f11c7f63SJim Harris void scif_sas_domain_continue_clear_affiliation(
1365f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain
1366f11c7f63SJim Harris )
1367f11c7f63SJim Harris {
1368f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * smp_device =
1369f11c7f63SJim Harris scif_sas_domain_find_device_has_scheduled_activity(
1370f11c7f63SJim Harris fw_domain,
1371f11c7f63SJim Harris SCIF_SAS_SMP_REMOTE_DEVICE_ACTIVITY_CLEAR_AFFILIATION
1372f11c7f63SJim Harris );
1373f11c7f63SJim Harris
1374f11c7f63SJim Harris if (smp_device != NULL)
1375f11c7f63SJim Harris scif_sas_smp_remote_device_start_clear_affiliation(smp_device);
1376f11c7f63SJim Harris else
1377f11c7f63SJim Harris {
1378f11c7f63SJim Harris //This domain has done clear affiliation.
1379f11c7f63SJim Harris SCIF_SAS_CONTROLLER_T * fw_controller = fw_domain->controller;
1380f11c7f63SJim Harris fw_controller->current_domain_to_clear_affiliation++;
1381f11c7f63SJim Harris
1382f11c7f63SJim Harris //let controller continue to clear affiliation on other domains.
1383f11c7f63SJim Harris scif_sas_controller_clear_affiliation(fw_domain->controller);
1384f11c7f63SJim Harris }
1385f11c7f63SJim Harris }
1386f11c7f63SJim Harris
1387f11c7f63SJim Harris
1388f11c7f63SJim Harris /**
1389f11c7f63SJim Harris * @brief This method releases resource for a framework domain.
1390f11c7f63SJim Harris *
1391f11c7f63SJim Harris * @param[in] fw_controller This parameter specifies the framework
1392f11c7f63SJim Harris * controller, its associated domain's resources are to be released.
1393f11c7f63SJim Harris * @param[in] fw_domain This parameter specifies the framework
1394f11c7f63SJim Harris * domain whose resources are to be released.
1395f11c7f63SJim Harris */
scif_sas_domain_release_resource(SCIF_SAS_CONTROLLER_T * fw_controller,SCIF_SAS_DOMAIN_T * fw_domain)1396f11c7f63SJim Harris void scif_sas_domain_release_resource(
1397f11c7f63SJim Harris SCIF_SAS_CONTROLLER_T * fw_controller,
1398f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain
1399f11c7f63SJim Harris )
1400f11c7f63SJim Harris {
1401f11c7f63SJim Harris if (fw_domain->operation.timer != NULL)
1402f11c7f63SJim Harris {
1403f11c7f63SJim Harris scif_cb_timer_destroy(fw_controller, fw_domain->operation.timer);
1404f11c7f63SJim Harris fw_domain->operation.timer = NULL;
1405f11c7f63SJim Harris }
1406f11c7f63SJim Harris }
1407f11c7f63SJim Harris
1408f11c7f63SJim Harris
1409f11c7f63SJim Harris /**
1410f11c7f63SJim Harris * @brief This method finds the a EA device that has target reset scheduled.
1411f11c7f63SJim Harris *
1412f11c7f63SJim Harris * @param[in] fw_domain The framework domain object
1413f11c7f63SJim Harris *
1414f11c7f63SJim Harris * @return SCIF_SAS_REMOTE_DEVICE_T The EA device that has target reset scheduled.
1415f11c7f63SJim Harris */
scif_sas_domain_find_next_ea_target_reset(SCIF_SAS_DOMAIN_T * fw_domain)1416f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * scif_sas_domain_find_next_ea_target_reset(
1417f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain
1418f11c7f63SJim Harris )
1419f11c7f63SJim Harris {
1420f11c7f63SJim Harris SCI_ABSTRACT_ELEMENT_T * current_element;
1421f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * current_device;
1422f11c7f63SJim Harris
1423f11c7f63SJim Harris SCIF_LOG_TRACE((
1424f11c7f63SJim Harris sci_base_object_get_logger(fw_domain),
1425f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN,
1426f11c7f63SJim Harris "scif_sas_domain_find_next_ea_target_reset(0x%x) enter\n",
1427f11c7f63SJim Harris fw_domain
1428f11c7f63SJim Harris ));
1429f11c7f63SJim Harris
1430453130d9SPedro F. Giffuni //search through domain's device list to find the first sata device on spinup_hold
1431f11c7f63SJim Harris current_element = sci_abstract_list_get_front(&fw_domain->remote_device_list);
1432f11c7f63SJim Harris while (current_element != NULL )
1433f11c7f63SJim Harris {
1434f11c7f63SJim Harris current_device = (SCIF_SAS_REMOTE_DEVICE_T *)
1435f11c7f63SJim Harris sci_abstract_list_get_object(current_element);
1436f11c7f63SJim Harris
1437f11c7f63SJim Harris current_element = sci_abstract_list_get_next(current_element);
1438f11c7f63SJim Harris
1439f11c7f63SJim Harris if ( current_device->ea_target_reset_request_scheduled != NULL )
1440f11c7f63SJim Harris {
1441f11c7f63SJim Harris return current_device;
1442f11c7f63SJim Harris }
1443f11c7f63SJim Harris }
1444f11c7f63SJim Harris
1445f11c7f63SJim Harris return NULL;
1446f11c7f63SJim Harris }
1447f11c7f63SJim Harris
1448f11c7f63SJim Harris #if !defined(DISABLE_WIDE_PORTED_TARGETS)
1449f11c7f63SJim Harris /**
1450f11c7f63SJim Harris * @brief This method update the direct attached device port width.
1451f11c7f63SJim Harris *
1452f11c7f63SJim Harris * @param[in] fw_domain The framework domain object
1453f11c7f63SJim Harris * @param[in] port The associated port object which recently has link up/down
1454f11c7f63SJim Harris * event happened.
1455f11c7f63SJim Harris *
1456f11c7f63SJim Harris * @return none
1457f11c7f63SJim Harris */
scif_sas_domain_update_device_port_width(SCIF_SAS_DOMAIN_T * fw_domain,SCI_PORT_HANDLE_T port)1458f11c7f63SJim Harris void scif_sas_domain_update_device_port_width(
1459f11c7f63SJim Harris SCIF_SAS_DOMAIN_T * fw_domain,
1460f11c7f63SJim Harris SCI_PORT_HANDLE_T port
1461f11c7f63SJim Harris )
1462f11c7f63SJim Harris {
1463f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * fw_device;
1464f11c7f63SJim Harris SCIC_PORT_PROPERTIES_T properties;
1465f11c7f63SJim Harris U8 new_port_width = 0;
1466f11c7f63SJim Harris
1467f11c7f63SJim Harris SCIF_LOG_TRACE((
1468f11c7f63SJim Harris sci_base_object_get_logger(fw_domain),
1469f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN,
1470f11c7f63SJim Harris "scif_sas_domain_update_device_port_width(0x%x, 0x%x) enter\n",
1471f11c7f63SJim Harris fw_domain, port
1472f11c7f63SJim Harris ));
1473f11c7f63SJim Harris
1474f11c7f63SJim Harris scic_port_get_properties(port, &properties);
1475f11c7f63SJim Harris
1476f11c7f63SJim Harris fw_device = (SCIF_SAS_REMOTE_DEVICE_T *)
1477f11c7f63SJim Harris scif_domain_get_device_by_sas_address(
1478f11c7f63SJim Harris fw_domain, &properties.remote.sas_address
1479f11c7f63SJim Harris );
1480f11c7f63SJim Harris
1481f11c7f63SJim Harris // If the device already existed in the domain, it is a wide port SSP target,
1482f11c7f63SJim Harris // we need to update its port width.
1483f11c7f63SJim Harris if (fw_device != SCI_INVALID_HANDLE)
1484f11c7f63SJim Harris {
1485f11c7f63SJim Harris SMP_DISCOVER_RESPONSE_PROTOCOLS_T dev_protocols;
1486f11c7f63SJim Harris scic_remote_device_get_protocols(fw_device->core_object, &dev_protocols);
1487f11c7f63SJim Harris
1488f11c7f63SJim Harris if (dev_protocols.u.bits.attached_ssp_target)
1489f11c7f63SJim Harris {
1490f11c7f63SJim Harris //Get accurate port width from port's phy mask for a DA device.
1491f11c7f63SJim Harris SCI_GET_BITS_SET_COUNT(properties.phy_mask, new_port_width);
1492f11c7f63SJim Harris
1493f11c7f63SJim Harris scif_sas_remote_device_update_port_width(fw_device, new_port_width);
1494f11c7f63SJim Harris }
1495f11c7f63SJim Harris }
1496f11c7f63SJim Harris }
1497f11c7f63SJim Harris #endif //#if !defined(DISABLE_WIDE_PORTED_TARGETS)
1498f11c7f63SJim Harris
1499f11c7f63SJim Harris
1500f11c7f63SJim Harris #ifdef SCI_LOGGING
1501f11c7f63SJim Harris /**
1502f11c7f63SJim Harris * This method will turn on logging of domain state changes.
1503f11c7f63SJim Harris *
1504f11c7f63SJim Harris * @param[in] fw_domain The domain for which the state logging is to be turned
1505f11c7f63SJim Harris * on.
1506f11c7f63SJim Harris */
scif_sas_domain_initialize_state_logging(SCIF_SAS_DOMAIN_T * fw_domain)1507f11c7f63SJim Harris void scif_sas_domain_initialize_state_logging(
1508f11c7f63SJim Harris SCIF_SAS_DOMAIN_T *fw_domain
1509f11c7f63SJim Harris )
1510f11c7f63SJim Harris {
1511f11c7f63SJim Harris sci_base_state_machine_logger_initialize(
1512f11c7f63SJim Harris &fw_domain->parent.state_machine_logger,
1513f11c7f63SJim Harris &fw_domain->parent.state_machine,
1514f11c7f63SJim Harris &fw_domain->parent.parent,
1515f11c7f63SJim Harris scif_cb_logger_log_states,
1516f11c7f63SJim Harris "SCIF_SAS_DOMAIN_T", "base state machine",
1517f11c7f63SJim Harris SCIF_LOG_OBJECT_DOMAIN
1518f11c7f63SJim Harris );
1519f11c7f63SJim Harris }
1520f11c7f63SJim Harris
1521f11c7f63SJim Harris /**
1522f11c7f63SJim Harris * This method will turn off logging of domain state changes.
1523f11c7f63SJim Harris *
1524f11c7f63SJim Harris * @param[in] fw_domain The domain for which the state logging is to be turned
1525f11c7f63SJim Harris * off.
1526f11c7f63SJim Harris */
scif_sas_domain_deinitialize_state_logging(SCIF_SAS_DOMAIN_T * fw_domain)1527f11c7f63SJim Harris void scif_sas_domain_deinitialize_state_logging(
1528f11c7f63SJim Harris SCIF_SAS_DOMAIN_T *fw_domain
1529f11c7f63SJim Harris )
1530f11c7f63SJim Harris {
1531f11c7f63SJim Harris sci_base_state_machine_logger_deinitialize(
1532f11c7f63SJim Harris &fw_domain->parent.state_machine_logger,
1533f11c7f63SJim Harris &fw_domain->parent.state_machine
1534f11c7f63SJim Harris );
1535f11c7f63SJim Harris }
1536f11c7f63SJim Harris #endif
1537