xref: /freebsd/sys/dev/isci/scil/scic_sds_controller.c (revision 685dc743dc3b5645e34836464128e1c0558b404b)
1f11c7f63SJim Harris /*-
2718cf2ccSPedro F. Giffuni  * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
3718cf2ccSPedro 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 SCIC_SDS_CONTROLLER
60f11c7f63SJim Harris  *        public, protected, and private methods.
61f11c7f63SJim Harris  */
62f11c7f63SJim Harris 
63f11c7f63SJim Harris #include <dev/isci/types.h>
64f11c7f63SJim Harris #include <dev/isci/scil/sci_util.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_phy.h>
68f11c7f63SJim Harris #include <dev/isci/scil/scic_remote_device.h>
69f11c7f63SJim Harris #include <dev/isci/scil/scic_user_callback.h>
70f11c7f63SJim Harris #include <dev/isci/scil/scic_sds_pci.h>
71f11c7f63SJim Harris #include <dev/isci/scil/scic_sds_library.h>
72f11c7f63SJim Harris #include <dev/isci/scil/scic_sds_controller.h>
73f11c7f63SJim Harris #include <dev/isci/scil/scic_sds_controller_registers.h>
74f11c7f63SJim Harris #include <dev/isci/scil/scic_sds_port.h>
75f11c7f63SJim Harris #include <dev/isci/scil/scic_sds_phy.h>
76f11c7f63SJim Harris #include <dev/isci/scil/scic_sds_remote_device.h>
77f11c7f63SJim Harris #include <dev/isci/scil/scic_sds_request.h>
78f11c7f63SJim Harris #include <dev/isci/scil/scic_sds_logger.h>
79f11c7f63SJim Harris #include <dev/isci/scil/scic_sds_port_configuration_agent.h>
80f11c7f63SJim Harris #include <dev/isci/scil/scu_constants.h>
81f11c7f63SJim Harris #include <dev/isci/scil/scu_event_codes.h>
82f11c7f63SJim Harris #include <dev/isci/scil/scu_completion_codes.h>
83f11c7f63SJim Harris #include <dev/isci/scil/scu_task_context.h>
84f11c7f63SJim Harris #include <dev/isci/scil/scu_remote_node_context.h>
85f11c7f63SJim Harris #include <dev/isci/scil/scu_unsolicited_frame.h>
86f11c7f63SJim Harris #include <dev/isci/scil/intel_pci.h>
87f11c7f63SJim Harris #include <dev/isci/scil/scic_sgpio.h>
88f11c7f63SJim Harris #include <dev/isci/scil/scic_sds_phy_registers.h>
89f11c7f63SJim Harris 
90f11c7f63SJim Harris #define SCU_CONTEXT_RAM_INIT_STALL_TIME      200
91f11c7f63SJim Harris #define SCIC_SDS_CONTROLLER_MIN_TIMER_COUNT  3
92f11c7f63SJim Harris #define SCIC_SDS_CONTROLLER_MAX_TIMER_COUNT  3
93f11c7f63SJim Harris 
94f11c7f63SJim Harris #define SCU_MAX_ZPT_DWORD_INDEX              131
95f11c7f63SJim Harris 
96f11c7f63SJim Harris /**
97f11c7f63SJim Harris  * The number of milliseconds to wait for a phy to start.
98f11c7f63SJim Harris  */
99f11c7f63SJim Harris #define SCIC_SDS_CONTROLLER_PHY_START_TIMEOUT      100
100f11c7f63SJim Harris 
101f11c7f63SJim Harris /**
102f11c7f63SJim Harris  * The number of milliseconds to wait while a given phy is consuming
103f11c7f63SJim Harris  * power before allowing another set of phys to consume power.
104f11c7f63SJim Harris  * Ultimately, this will be specified by OEM parameter.
105f11c7f63SJim Harris  */
106f11c7f63SJim Harris #define SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL 500
107f11c7f63SJim Harris 
108f11c7f63SJim Harris /**
109f11c7f63SJim Harris  * This macro will return the cycle bit of the completion queue entry
110f11c7f63SJim Harris  */
111f11c7f63SJim Harris #define COMPLETION_QUEUE_CYCLE_BIT(x) ((x) & 0x80000000)
112f11c7f63SJim Harris 
113f11c7f63SJim Harris /**
114f11c7f63SJim Harris  * This macro will normalize the completion queue get pointer so its value
115f11c7f63SJim Harris  * can be used as an index into an array
116f11c7f63SJim Harris  */
117f11c7f63SJim Harris #define NORMALIZE_GET_POINTER(x) \
118f11c7f63SJim Harris    ((x) & SMU_COMPLETION_QUEUE_GET_POINTER_MASK)
119f11c7f63SJim Harris 
120f11c7f63SJim Harris /**
121f11c7f63SJim Harris  *  This macro will normalize the completion queue put pointer so its value
122f11c7f63SJim Harris  *  can be used as an array inde
123f11c7f63SJim Harris  */
124f11c7f63SJim Harris #define NORMALIZE_PUT_POINTER(x) \
125f11c7f63SJim Harris    ((x) & SMU_COMPLETION_QUEUE_PUT_POINTER_MASK)
126f11c7f63SJim Harris 
127f11c7f63SJim Harris 
128f11c7f63SJim Harris /**
129f11c7f63SJim Harris  * This macro will normalize the completion queue cycle pointer so it
130f11c7f63SJim Harris  * matches the completion queue cycle bit
131f11c7f63SJim Harris  */
132f11c7f63SJim Harris #define NORMALIZE_GET_POINTER_CYCLE_BIT(x) \
133f11c7f63SJim Harris    (((U32)(SMU_CQGR_CYCLE_BIT & (x))) << (31 - SMU_COMPLETION_QUEUE_GET_CYCLE_BIT_SHIFT))
134f11c7f63SJim Harris 
135f11c7f63SJim Harris /**
136f11c7f63SJim Harris  * This macro will normalize the completion queue event entry so its value
137f11c7f63SJim Harris  * can be used as an index.
138f11c7f63SJim Harris  */
139f11c7f63SJim Harris #define NORMALIZE_EVENT_POINTER(x) \
140f11c7f63SJim Harris    ( \
141f11c7f63SJim Harris         ((U32)((x) & SMU_COMPLETION_QUEUE_GET_EVENT_POINTER_MASK)) \
142f11c7f63SJim Harris      >> SMU_COMPLETION_QUEUE_GET_EVENT_POINTER_SHIFT \
143f11c7f63SJim Harris    )
144f11c7f63SJim Harris 
145f11c7f63SJim Harris /**
146f11c7f63SJim Harris  * This macro will increment the controllers completion queue index value
147f11c7f63SJim Harris  * and possibly toggle the cycle bit if the completion queue index wraps
148f11c7f63SJim Harris  * back to 0.
149f11c7f63SJim Harris  */
150f11c7f63SJim Harris #define INCREMENT_COMPLETION_QUEUE_GET(controller, index, cycle) \
151f11c7f63SJim Harris    INCREMENT_QUEUE_GET( \
152f11c7f63SJim Harris       (index), \
153f11c7f63SJim Harris       (cycle), \
154f11c7f63SJim Harris       (controller)->completion_queue_entries, \
155f11c7f63SJim Harris       SMU_CQGR_CYCLE_BIT \
156f11c7f63SJim Harris    )
157f11c7f63SJim Harris 
158f11c7f63SJim Harris /**
159f11c7f63SJim Harris  * This macro will increment the controllers event queue index value and
160f11c7f63SJim Harris  * possibly toggle the event cycle bit if the event queue index wraps back
161f11c7f63SJim Harris  * to 0.
162f11c7f63SJim Harris  */
163f11c7f63SJim Harris #define INCREMENT_EVENT_QUEUE_GET(controller, index, cycle) \
164f11c7f63SJim Harris    INCREMENT_QUEUE_GET( \
165f11c7f63SJim Harris       (index), \
166f11c7f63SJim Harris       (cycle), \
167f11c7f63SJim Harris       (controller)->completion_event_entries, \
168f11c7f63SJim Harris       SMU_CQGR_EVENT_CYCLE_BIT \
169f11c7f63SJim Harris    )
170f11c7f63SJim Harris 
171f11c7f63SJim Harris //****************************************************************************-
172f11c7f63SJim Harris //* SCIC SDS Controller Initialization Methods
173f11c7f63SJim Harris //****************************************************************************-
174f11c7f63SJim Harris 
175f11c7f63SJim Harris /**
176f11c7f63SJim Harris  * @brief This timer is used to start another phy after we have given up on
177f11c7f63SJim Harris  *        the previous phy to transition to the ready state.
178f11c7f63SJim Harris  *
179f11c7f63SJim Harris  * @param[in] controller
180f11c7f63SJim Harris  */
181f11c7f63SJim Harris static
scic_sds_controller_phy_startup_timeout_handler(void * controller)182f11c7f63SJim Harris void scic_sds_controller_phy_startup_timeout_handler(
183f11c7f63SJim Harris    void *controller
184f11c7f63SJim Harris )
185f11c7f63SJim Harris {
186f11c7f63SJim Harris    SCI_STATUS status;
187f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
188f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
189f11c7f63SJim Harris 
190f11c7f63SJim Harris    this_controller->phy_startup_timer_pending = FALSE;
191f11c7f63SJim Harris 
192f11c7f63SJim Harris    status = SCI_FAILURE;
193f11c7f63SJim Harris 
194f11c7f63SJim Harris    while (status != SCI_SUCCESS)
195f11c7f63SJim Harris    {
196f11c7f63SJim Harris       status = scic_sds_controller_start_next_phy(this_controller);
197f11c7f63SJim Harris    }
198f11c7f63SJim Harris }
199f11c7f63SJim Harris 
200f11c7f63SJim Harris /**
201f11c7f63SJim Harris  * This method initializes the phy startup operations for controller start.
202f11c7f63SJim Harris  *
203f11c7f63SJim Harris  * @param this_controller
204f11c7f63SJim Harris  */
205f11c7f63SJim Harris static
scic_sds_controller_initialize_phy_startup(SCIC_SDS_CONTROLLER_T * this_controller)206f11c7f63SJim Harris SCI_STATUS scic_sds_controller_initialize_phy_startup(
207f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
208f11c7f63SJim Harris )
209f11c7f63SJim Harris {
210f11c7f63SJim Harris    this_controller->phy_startup_timer = scic_cb_timer_create(
211f11c7f63SJim Harris       this_controller,
212f11c7f63SJim Harris       scic_sds_controller_phy_startup_timeout_handler,
213f11c7f63SJim Harris       this_controller
214f11c7f63SJim Harris    );
215f11c7f63SJim Harris 
216f11c7f63SJim Harris    if (this_controller->phy_startup_timer == NULL)
217f11c7f63SJim Harris    {
218f11c7f63SJim Harris       return SCI_FAILURE_INSUFFICIENT_RESOURCES;
219f11c7f63SJim Harris    }
220f11c7f63SJim Harris    else
221f11c7f63SJim Harris    {
222f11c7f63SJim Harris       this_controller->next_phy_to_start = 0;
223f11c7f63SJim Harris       this_controller->phy_startup_timer_pending = FALSE;
224f11c7f63SJim Harris    }
225f11c7f63SJim Harris 
226f11c7f63SJim Harris    return SCI_SUCCESS;
227f11c7f63SJim Harris }
228f11c7f63SJim Harris 
229f11c7f63SJim Harris /**
230f11c7f63SJim Harris  * This method initializes the power control operations for the controller
231f11c7f63SJim Harris  * object.
232f11c7f63SJim Harris  *
233f11c7f63SJim Harris  * @param this_controller
234f11c7f63SJim Harris  */
scic_sds_controller_initialize_power_control(SCIC_SDS_CONTROLLER_T * this_controller)235f11c7f63SJim Harris void scic_sds_controller_initialize_power_control(
236f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
237f11c7f63SJim Harris )
238f11c7f63SJim Harris {
239f11c7f63SJim Harris    this_controller->power_control.timer = scic_cb_timer_create(
240f11c7f63SJim Harris       this_controller,
241f11c7f63SJim Harris       scic_sds_controller_power_control_timer_handler,
242f11c7f63SJim Harris       this_controller
243f11c7f63SJim Harris    );
244f11c7f63SJim Harris 
245f11c7f63SJim Harris    memset(
246f11c7f63SJim Harris       this_controller->power_control.requesters,
247f11c7f63SJim Harris       0,
248f11c7f63SJim Harris       sizeof(this_controller->power_control.requesters)
249f11c7f63SJim Harris    );
250f11c7f63SJim Harris 
251f11c7f63SJim Harris    this_controller->power_control.phys_waiting = 0;
252f11c7f63SJim Harris    this_controller->power_control.remote_devices_granted_power = 0;
253f11c7f63SJim Harris }
254f11c7f63SJim Harris 
255f11c7f63SJim Harris // ---------------------------------------------------------------------------
256f11c7f63SJim Harris 
257f11c7f63SJim Harris #define SCU_REMOTE_NODE_CONTEXT_ALIGNMENT       (32)
258f11c7f63SJim Harris #define SCU_TASK_CONTEXT_ALIGNMENT              (256)
259f11c7f63SJim Harris #define SCU_UNSOLICITED_FRAME_ADDRESS_ALIGNMENT (64)
260f11c7f63SJim Harris #define SCU_UNSOLICITED_FRAME_BUFFER_ALIGNMENT  (1024)
261f11c7f63SJim Harris #define SCU_UNSOLICITED_FRAME_HEADER_ALIGNMENT  (64)
262f11c7f63SJim Harris 
263f11c7f63SJim Harris // ---------------------------------------------------------------------------
264f11c7f63SJim Harris 
265f11c7f63SJim Harris /**
266f11c7f63SJim Harris  * @brief This method builds the memory descriptor table for this
267f11c7f63SJim Harris  *        controller.
268f11c7f63SJim Harris  *
269f11c7f63SJim Harris  * @param[in] this_controller This parameter specifies the controller
270f11c7f63SJim Harris  *            object for which to build the memory table.
271f11c7f63SJim Harris  *
272f11c7f63SJim Harris  * @return none
273f11c7f63SJim Harris  */
scic_sds_controller_build_memory_descriptor_table(SCIC_SDS_CONTROLLER_T * this_controller)274f11c7f63SJim Harris void scic_sds_controller_build_memory_descriptor_table(
275f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
276f11c7f63SJim Harris )
277f11c7f63SJim Harris {
278f11c7f63SJim Harris    sci_base_mde_construct(
279f11c7f63SJim Harris       &this_controller->memory_descriptors[SCU_MDE_COMPLETION_QUEUE],
280f11c7f63SJim Harris       SCU_COMPLETION_RAM_ALIGNMENT,
281f11c7f63SJim Harris       (sizeof(U32) * this_controller->completion_queue_entries),
282f11c7f63SJim Harris       (SCI_MDE_ATTRIBUTE_CACHEABLE | SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS)
283f11c7f63SJim Harris    );
284f11c7f63SJim Harris 
285f11c7f63SJim Harris    sci_base_mde_construct(
286f11c7f63SJim Harris       &this_controller->memory_descriptors[SCU_MDE_REMOTE_NODE_CONTEXT],
287f11c7f63SJim Harris       SCU_REMOTE_NODE_CONTEXT_ALIGNMENT,
288f11c7f63SJim Harris       this_controller->remote_node_entries * sizeof(SCU_REMOTE_NODE_CONTEXT_T),
289f11c7f63SJim Harris       SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS
290f11c7f63SJim Harris    );
291f11c7f63SJim Harris 
292f11c7f63SJim Harris    sci_base_mde_construct(
293f11c7f63SJim Harris       &this_controller->memory_descriptors[SCU_MDE_TASK_CONTEXT],
294f11c7f63SJim Harris       SCU_TASK_CONTEXT_ALIGNMENT,
295f11c7f63SJim Harris       this_controller->task_context_entries * sizeof(SCU_TASK_CONTEXT_T),
296f11c7f63SJim Harris       SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS
297f11c7f63SJim Harris    );
298f11c7f63SJim Harris 
299f11c7f63SJim Harris    // The UF buffer address table size must be programmed to a power
300f11c7f63SJim Harris    // of 2.  Find the first power of 2 that is equal to or greater then
301f11c7f63SJim Harris    // the number of unsolicited frame buffers to be utilized.
302f11c7f63SJim Harris    scic_sds_unsolicited_frame_control_set_address_table_count(
303f11c7f63SJim Harris       &this_controller->uf_control
304f11c7f63SJim Harris    );
305f11c7f63SJim Harris 
306f11c7f63SJim Harris    sci_base_mde_construct(
307f11c7f63SJim Harris       &this_controller->memory_descriptors[SCU_MDE_UF_BUFFER],
308f11c7f63SJim Harris       SCU_UNSOLICITED_FRAME_BUFFER_ALIGNMENT,
309f11c7f63SJim Harris       scic_sds_unsolicited_frame_control_get_mde_size(this_controller->uf_control),
310f11c7f63SJim Harris       SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS
311f11c7f63SJim Harris    );
312f11c7f63SJim Harris }
313f11c7f63SJim Harris 
314f11c7f63SJim Harris /**
315f11c7f63SJim Harris  * @brief This method validates the driver supplied memory descriptor
316f11c7f63SJim Harris  *        table.
317f11c7f63SJim Harris  *
318f11c7f63SJim Harris  * @param[in] this_controller
319f11c7f63SJim Harris  *
320f11c7f63SJim Harris  * @return SCI_STATUS
321f11c7f63SJim Harris  */
scic_sds_controller_validate_memory_descriptor_table(SCIC_SDS_CONTROLLER_T * this_controller)322f11c7f63SJim Harris SCI_STATUS scic_sds_controller_validate_memory_descriptor_table(
323f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
324f11c7f63SJim Harris )
325f11c7f63SJim Harris {
326f11c7f63SJim Harris    BOOL mde_list_valid;
327f11c7f63SJim Harris 
328f11c7f63SJim Harris    mde_list_valid = sci_base_mde_is_valid(
329f11c7f63SJim Harris       &this_controller->memory_descriptors[SCU_MDE_COMPLETION_QUEUE],
330f11c7f63SJim Harris       SCU_COMPLETION_RAM_ALIGNMENT,
331f11c7f63SJim Harris       (sizeof(U32) * this_controller->completion_queue_entries),
332f11c7f63SJim Harris       (SCI_MDE_ATTRIBUTE_CACHEABLE | SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS)
333f11c7f63SJim Harris    );
334f11c7f63SJim Harris 
335f11c7f63SJim Harris    if (mde_list_valid == FALSE)
336f11c7f63SJim Harris       return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD;
337f11c7f63SJim Harris 
338f11c7f63SJim Harris    mde_list_valid = sci_base_mde_is_valid(
339f11c7f63SJim Harris       &this_controller->memory_descriptors[SCU_MDE_REMOTE_NODE_CONTEXT],
340f11c7f63SJim Harris       SCU_REMOTE_NODE_CONTEXT_ALIGNMENT,
341f11c7f63SJim Harris       this_controller->remote_node_entries * sizeof(SCU_REMOTE_NODE_CONTEXT_T),
342f11c7f63SJim Harris       SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS
343f11c7f63SJim Harris    );
344f11c7f63SJim Harris 
345f11c7f63SJim Harris    if (mde_list_valid == FALSE)
346f11c7f63SJim Harris       return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD;
347f11c7f63SJim Harris 
348f11c7f63SJim Harris    mde_list_valid = sci_base_mde_is_valid(
349f11c7f63SJim Harris       &this_controller->memory_descriptors[SCU_MDE_TASK_CONTEXT],
350f11c7f63SJim Harris       SCU_TASK_CONTEXT_ALIGNMENT,
351f11c7f63SJim Harris       this_controller->task_context_entries * sizeof(SCU_TASK_CONTEXT_T),
352f11c7f63SJim Harris       SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS
353f11c7f63SJim Harris    );
354f11c7f63SJim Harris 
355f11c7f63SJim Harris    if (mde_list_valid == FALSE)
356f11c7f63SJim Harris       return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD;
357f11c7f63SJim Harris 
358f11c7f63SJim Harris    mde_list_valid = sci_base_mde_is_valid(
359f11c7f63SJim Harris       &this_controller->memory_descriptors[SCU_MDE_UF_BUFFER],
360f11c7f63SJim Harris       SCU_UNSOLICITED_FRAME_BUFFER_ALIGNMENT,
361f11c7f63SJim Harris       scic_sds_unsolicited_frame_control_get_mde_size(this_controller->uf_control),
362f11c7f63SJim Harris       SCI_MDE_ATTRIBUTE_PHYSICALLY_CONTIGUOUS
363f11c7f63SJim Harris    );
364f11c7f63SJim Harris 
365f11c7f63SJim Harris    if (mde_list_valid == FALSE)
366f11c7f63SJim Harris       return SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD;
367f11c7f63SJim Harris 
368f11c7f63SJim Harris    return SCI_SUCCESS;
369f11c7f63SJim Harris }
370f11c7f63SJim Harris 
371f11c7f63SJim Harris /**
372f11c7f63SJim Harris  * @brief This method initializes the controller with the physical memory
373f11c7f63SJim Harris  *        addresses that are used to communicate with the driver.
374f11c7f63SJim Harris  *
375f11c7f63SJim Harris  * @param[in] this_controller
376f11c7f63SJim Harris  *
377f11c7f63SJim Harris  * @return none
378f11c7f63SJim Harris  */
scic_sds_controller_ram_initialization(SCIC_SDS_CONTROLLER_T * this_controller)379f11c7f63SJim Harris void scic_sds_controller_ram_initialization(
380f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
381f11c7f63SJim Harris )
382f11c7f63SJim Harris {
383f11c7f63SJim Harris    SCI_PHYSICAL_MEMORY_DESCRIPTOR_T *mde;
384f11c7f63SJim Harris 
385f11c7f63SJim Harris    // The completion queue is actually placed in cacheable memory
386f11c7f63SJim Harris    // Therefore it no longer comes out of memory in the MDL.
387f11c7f63SJim Harris    mde = &this_controller->memory_descriptors[SCU_MDE_COMPLETION_QUEUE];
388f11c7f63SJim Harris    this_controller->completion_queue = (U32*) mde->virtual_address;
389f11c7f63SJim Harris    SMU_CQBAR_WRITE(this_controller, mde->physical_address);
390f11c7f63SJim Harris 
391f11c7f63SJim Harris    // Program the location of the Remote Node Context table
392f11c7f63SJim Harris    // into the SCU.
393f11c7f63SJim Harris    mde = &this_controller->memory_descriptors[SCU_MDE_REMOTE_NODE_CONTEXT];
394f11c7f63SJim Harris    this_controller->remote_node_context_table = (SCU_REMOTE_NODE_CONTEXT_T *)
395f11c7f63SJim Harris                                                 mde->virtual_address;
396f11c7f63SJim Harris    SMU_RNCBAR_WRITE(this_controller, mde->physical_address);
397f11c7f63SJim Harris 
398f11c7f63SJim Harris    // Program the location of the Task Context table into the SCU.
399f11c7f63SJim Harris    mde = &this_controller->memory_descriptors[SCU_MDE_TASK_CONTEXT];
400f11c7f63SJim Harris    this_controller->task_context_table = (SCU_TASK_CONTEXT_T *)
401f11c7f63SJim Harris                                          mde->virtual_address;
402f11c7f63SJim Harris    SMU_HTTBAR_WRITE(this_controller, mde->physical_address);
403f11c7f63SJim Harris 
404f11c7f63SJim Harris    mde = &this_controller->memory_descriptors[SCU_MDE_UF_BUFFER];
405f11c7f63SJim Harris    scic_sds_unsolicited_frame_control_construct(
406f11c7f63SJim Harris       &this_controller->uf_control, mde, this_controller
407f11c7f63SJim Harris    );
408f11c7f63SJim Harris 
409f11c7f63SJim Harris    // Inform the silicon as to the location of the UF headers and
410f11c7f63SJim Harris    // address table.
411f11c7f63SJim Harris    SCU_UFHBAR_WRITE(
412f11c7f63SJim Harris       this_controller,
413f11c7f63SJim Harris       this_controller->uf_control.headers.physical_address);
414f11c7f63SJim Harris    SCU_PUFATHAR_WRITE(
415f11c7f63SJim Harris       this_controller,
416f11c7f63SJim Harris       this_controller->uf_control.address_table.physical_address);
417f11c7f63SJim Harris 
418f11c7f63SJim Harris    //enable the ECC correction and detection.
419f11c7f63SJim Harris    SCU_SECR0_WRITE(
420f11c7f63SJim Harris       this_controller,
421f11c7f63SJim Harris       (SIGNLE_BIT_ERROR_CORRECTION_ENABLE
422f11c7f63SJim Harris        | MULTI_BIT_ERROR_REPORTING_ENABLE
423f11c7f63SJim Harris        | SINGLE_BIT_ERROR_REPORTING_ENABLE) );
424f11c7f63SJim Harris    SCU_SECR1_WRITE(
425f11c7f63SJim Harris       this_controller,
426f11c7f63SJim Harris       (SIGNLE_BIT_ERROR_CORRECTION_ENABLE
427f11c7f63SJim Harris        | MULTI_BIT_ERROR_REPORTING_ENABLE
428f11c7f63SJim Harris        | SINGLE_BIT_ERROR_REPORTING_ENABLE) );
429f11c7f63SJim Harris }
430f11c7f63SJim Harris 
431f11c7f63SJim Harris /**
432f11c7f63SJim Harris  * @brief This method initializes the task context data for the controller.
433f11c7f63SJim Harris  *
434f11c7f63SJim Harris  * @param[in] this_controller
435f11c7f63SJim Harris  *
436f11c7f63SJim Harris  * @return none
437f11c7f63SJim Harris  */
scic_sds_controller_assign_task_entries(SCIC_SDS_CONTROLLER_T * this_controller)438f11c7f63SJim Harris void scic_sds_controller_assign_task_entries(
439f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
440f11c7f63SJim Harris )
441f11c7f63SJim Harris {
442f11c7f63SJim Harris    U32 task_assignment;
443f11c7f63SJim Harris 
444f11c7f63SJim Harris    // Assign all the TCs to function 0
445f11c7f63SJim Harris    // TODO: Do we actually need to read this register to write it back?
446f11c7f63SJim Harris    task_assignment = SMU_TCA_READ(this_controller, 0);
447f11c7f63SJim Harris 
448f11c7f63SJim Harris    task_assignment =
449f11c7f63SJim Harris       (
450f11c7f63SJim Harris           task_assignment
451f11c7f63SJim Harris         | (SMU_TCA_GEN_VAL(STARTING, 0))
452f11c7f63SJim Harris         | (SMU_TCA_GEN_VAL(ENDING,  this_controller->task_context_entries - 1))
453f11c7f63SJim Harris         | (SMU_TCA_GEN_BIT(RANGE_CHECK_ENABLE))
454f11c7f63SJim Harris       );
455f11c7f63SJim Harris 
456f11c7f63SJim Harris    SMU_TCA_WRITE(this_controller, 0, task_assignment);
457f11c7f63SJim Harris }
458f11c7f63SJim Harris 
459f11c7f63SJim Harris /**
460f11c7f63SJim Harris  * @brief This method initializes the hardware completion queue.
461f11c7f63SJim Harris  *
462f11c7f63SJim Harris  * @param[in] this_controller
463f11c7f63SJim Harris  */
scic_sds_controller_initialize_completion_queue(SCIC_SDS_CONTROLLER_T * this_controller)464f11c7f63SJim Harris void scic_sds_controller_initialize_completion_queue(
465f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
466f11c7f63SJim Harris )
467f11c7f63SJim Harris {
468f11c7f63SJim Harris    U32 index;
469f11c7f63SJim Harris    U32 completion_queue_control_value;
470f11c7f63SJim Harris    U32 completion_queue_get_value;
471f11c7f63SJim Harris    U32 completion_queue_put_value;
472f11c7f63SJim Harris 
473f11c7f63SJim Harris    this_controller->completion_queue_get = 0;
474f11c7f63SJim Harris 
475f11c7f63SJim Harris    completion_queue_control_value = (
476f11c7f63SJim Harris         SMU_CQC_QUEUE_LIMIT_SET(this_controller->completion_queue_entries - 1)
477f11c7f63SJim Harris       | SMU_CQC_EVENT_LIMIT_SET(this_controller->completion_event_entries - 1)
478f11c7f63SJim Harris    );
479f11c7f63SJim Harris 
480f11c7f63SJim Harris    SMU_CQC_WRITE(this_controller, completion_queue_control_value);
481f11c7f63SJim Harris 
482f11c7f63SJim Harris    // Set the completion queue get pointer and enable the queue
483f11c7f63SJim Harris    completion_queue_get_value = (
484f11c7f63SJim Harris         (SMU_CQGR_GEN_VAL(POINTER, 0))
485f11c7f63SJim Harris       | (SMU_CQGR_GEN_VAL(EVENT_POINTER, 0))
486f11c7f63SJim Harris       | (SMU_CQGR_GEN_BIT(ENABLE))
487f11c7f63SJim Harris       | (SMU_CQGR_GEN_BIT(EVENT_ENABLE))
488f11c7f63SJim Harris    );
489f11c7f63SJim Harris 
490f11c7f63SJim Harris    SMU_CQGR_WRITE(this_controller, completion_queue_get_value);
491f11c7f63SJim Harris 
492f11c7f63SJim Harris    this_controller->completion_queue_get = completion_queue_get_value;
493f11c7f63SJim Harris 
494f11c7f63SJim Harris    // Set the completion queue put pointer
495f11c7f63SJim Harris    completion_queue_put_value = (
496f11c7f63SJim Harris         (SMU_CQPR_GEN_VAL(POINTER, 0))
497f11c7f63SJim Harris       | (SMU_CQPR_GEN_VAL(EVENT_POINTER, 0))
498f11c7f63SJim Harris    );
499f11c7f63SJim Harris 
500f11c7f63SJim Harris    SMU_CQPR_WRITE(this_controller, completion_queue_put_value);
501f11c7f63SJim Harris 
502f11c7f63SJim Harris    // Initialize the cycle bit of the completion queue entries
503f11c7f63SJim Harris    for (index = 0; index < this_controller->completion_queue_entries; index++)
504f11c7f63SJim Harris    {
505f11c7f63SJim Harris       // If get.cycle_bit != completion_queue.cycle_bit
506f11c7f63SJim Harris       // its not a valid completion queue entry
507f11c7f63SJim Harris       // so at system start all entries are invalid
508f11c7f63SJim Harris       this_controller->completion_queue[index] = 0x80000000;
509f11c7f63SJim Harris    }
510f11c7f63SJim Harris }
511f11c7f63SJim Harris 
512f11c7f63SJim Harris /**
513f11c7f63SJim Harris  * @brief This method initializes the hardware unsolicited frame queue.
514f11c7f63SJim Harris  *
515f11c7f63SJim Harris  * @param[in] this_controller
516f11c7f63SJim Harris  */
scic_sds_controller_initialize_unsolicited_frame_queue(SCIC_SDS_CONTROLLER_T * this_controller)517f11c7f63SJim Harris void scic_sds_controller_initialize_unsolicited_frame_queue(
518f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
519f11c7f63SJim Harris )
520f11c7f63SJim Harris {
521f11c7f63SJim Harris    U32 frame_queue_control_value;
522f11c7f63SJim Harris    U32 frame_queue_get_value;
523f11c7f63SJim Harris    U32 frame_queue_put_value;
524f11c7f63SJim Harris 
525f11c7f63SJim Harris    // Write the queue size
526f11c7f63SJim Harris    frame_queue_control_value =
527f11c7f63SJim Harris       SCU_UFQC_GEN_VAL(QUEUE_SIZE, this_controller->uf_control.address_table.count);
528f11c7f63SJim Harris 
529f11c7f63SJim Harris    SCU_UFQC_WRITE(this_controller, frame_queue_control_value);
530f11c7f63SJim Harris 
531f11c7f63SJim Harris    // Setup the get pointer for the unsolicited frame queue
532f11c7f63SJim Harris    frame_queue_get_value = (
533f11c7f63SJim Harris          SCU_UFQGP_GEN_VAL(POINTER, 0)
534f11c7f63SJim Harris       |  SCU_UFQGP_GEN_BIT(ENABLE_BIT)
535f11c7f63SJim Harris       );
536f11c7f63SJim Harris 
537f11c7f63SJim Harris    SCU_UFQGP_WRITE(this_controller, frame_queue_get_value);
538f11c7f63SJim Harris 
539f11c7f63SJim Harris    // Setup the put pointer for the unsolicited frame queue
540f11c7f63SJim Harris    frame_queue_put_value = SCU_UFQPP_GEN_VAL(POINTER, 0);
541f11c7f63SJim Harris 
542f11c7f63SJim Harris    SCU_UFQPP_WRITE(this_controller, frame_queue_put_value);
543f11c7f63SJim Harris }
544f11c7f63SJim Harris 
545f11c7f63SJim Harris /**
546f11c7f63SJim Harris  * @brief This method enables the hardware port task scheduler.
547f11c7f63SJim Harris  *
548f11c7f63SJim Harris  * @param[in] this_controller
549f11c7f63SJim Harris  */
scic_sds_controller_enable_port_task_scheduler(SCIC_SDS_CONTROLLER_T * this_controller)550f11c7f63SJim Harris void scic_sds_controller_enable_port_task_scheduler(
551f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
552f11c7f63SJim Harris )
553f11c7f63SJim Harris {
554f11c7f63SJim Harris    U32 port_task_scheduler_value;
555f11c7f63SJim Harris 
556f11c7f63SJim Harris    port_task_scheduler_value = SCU_PTSGCR_READ(this_controller);
557f11c7f63SJim Harris 
558f11c7f63SJim Harris    port_task_scheduler_value |=
559f11c7f63SJim Harris       (SCU_PTSGCR_GEN_BIT(ETM_ENABLE) | SCU_PTSGCR_GEN_BIT(PTSG_ENABLE));
560f11c7f63SJim Harris 
561f11c7f63SJim Harris    SCU_PTSGCR_WRITE(this_controller, port_task_scheduler_value);
562f11c7f63SJim Harris }
563f11c7f63SJim Harris 
564f11c7f63SJim Harris // ---------------------------------------------------------------------------
565f11c7f63SJim Harris 
566f11c7f63SJim Harris #ifdef ARLINGTON_BUILD
567f11c7f63SJim Harris /**
568f11c7f63SJim Harris  * This method will read from the lexington status register.  This is required
569f11c7f63SJim Harris  * as a read fence to the lexington register writes.
570f11c7f63SJim Harris  *
571f11c7f63SJim Harris  * @param this_controller
572f11c7f63SJim Harris  */
scic_sds_controller_lex_status_read_fence(SCIC_SDS_CONTROLLER_T * this_controller)573f11c7f63SJim Harris void scic_sds_controller_lex_status_read_fence(
574f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
575f11c7f63SJim Harris )
576f11c7f63SJim Harris {
577f11c7f63SJim Harris    U32 lex_status;
578f11c7f63SJim Harris 
579f11c7f63SJim Harris    // Read Fence
580f11c7f63SJim Harris    lex_status = lex_register_read(
581f11c7f63SJim Harris                   this_controller, this_controller->lex_registers + 0xC4);
582f11c7f63SJim Harris 
583f11c7f63SJim Harris    SCIC_LOG_TRACE((
584f11c7f63SJim Harris       sci_base_object_get_logger(this_controller),
585f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
586f11c7f63SJim Harris       "Controller 0x%x lex_status = 0x%08x\n",
587f11c7f63SJim Harris       this_controller, lex_status
588f11c7f63SJim Harris    ));
589f11c7f63SJim Harris }
590f11c7f63SJim Harris 
591f11c7f63SJim Harris /**
592f11c7f63SJim Harris  * This method will initialize the arlington through the LEX_BAR.
593f11c7f63SJim Harris  *
594f11c7f63SJim Harris  * @param this_controller
595f11c7f63SJim Harris  */
scic_sds_controller_lex_atux_initialization(SCIC_SDS_CONTROLLER_T * this_controller)596f11c7f63SJim Harris void scic_sds_controller_lex_atux_initialization(
597f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
598f11c7f63SJim Harris )
599f11c7f63SJim Harris {
600f11c7f63SJim Harris    // 1. Reset all SCU PHY
601f11c7f63SJim Harris    lex_register_write(
602f11c7f63SJim Harris       this_controller, this_controller->lex_registers + 0x28, 0x0020FFFF) ;
603f11c7f63SJim Harris 
604f11c7f63SJim Harris    // 2. Write to LEX_CTRL
605f11c7f63SJim Harris    lex_register_write(
606f11c7f63SJim Harris       this_controller, this_controller->lex_registers + 0xC0, 0x00000700);
607f11c7f63SJim Harris 
608f11c7f63SJim Harris    scic_sds_controller_lex_status_read_fence(this_controller);
609f11c7f63SJim Harris 
610f11c7f63SJim Harris    // 3. Enable PCI Master
611f11c7f63SJim Harris    lex_register_write(
612f11c7f63SJim Harris       this_controller, this_controller->lex_registers + 0x70, 0x00000002);
613f11c7f63SJim Harris 
614f11c7f63SJim Harris    // 4. Enable SCU Register Clock Domain
615f11c7f63SJim Harris    lex_register_write(
616f11c7f63SJim Harris       this_controller, this_controller->lex_registers + 0xC0, 0x00000300);
617f11c7f63SJim Harris 
618f11c7f63SJim Harris    scic_sds_controller_lex_status_read_fence(this_controller);
619f11c7f63SJim Harris 
620f11c7f63SJim Harris    // 5.1 Release PHY-A Reg Reset
621f11c7f63SJim Harris    lex_register_write(
622f11c7f63SJim Harris       this_controller, this_controller->lex_registers + 0x28, 0x0000FFFF);
623f11c7f63SJim Harris 
624f11c7f63SJim Harris    // 5.2 Initialize the AFE for PHY-A
625f11c7f63SJim Harris    scic_sds_controller_afe_initialization(this_controller);
626f11c7f63SJim Harris 
627f11c7f63SJim Harris    scic_sds_controller_lex_status_read_fence(this_controller);
628f11c7f63SJim Harris 
629f11c7f63SJim Harris #if 0
630f11c7f63SJim Harris    // 5.3 Release PHY Reg Reset
631f11c7f63SJim Harris    lex_register_write(
632f11c7f63SJim Harris       this_controller, this_controller->lex_registers + 0x28, 0x0000FFFF);
633f11c7f63SJim Harris #endif
634f11c7f63SJim Harris 
635f11c7f63SJim Harris    // 6.1 Release PHY-B Reg Reset
636f11c7f63SJim Harris    lex_register_write(
637f11c7f63SJim Harris       this_controller, this_controller->lex_registers + 0x28, 0x0040FFFF) ;
638f11c7f63SJim Harris 
639f11c7f63SJim Harris    // 6.2 Initialize the AFE for PHY-B
640f11c7f63SJim Harris    scic_sds_controller_afe_initialization(this_controller);
641f11c7f63SJim Harris 
642f11c7f63SJim Harris    scic_sds_controller_lex_status_read_fence(this_controller);
643f11c7f63SJim Harris 
644f11c7f63SJim Harris #if 0
645f11c7f63SJim Harris    // 6.3 Release PHY-B Reg Reset
646f11c7f63SJim Harris    lex_register_write(
647f11c7f63SJim Harris       this_controller, this_controller->lex_registers + 0x28, 0x0040FFFF) ;
648f11c7f63SJim Harris #endif
649f11c7f63SJim Harris 
650f11c7f63SJim Harris    // 7. Enable SCU clock domaion
651f11c7f63SJim Harris    lex_register_write(
652f11c7f63SJim Harris       this_controller, this_controller->lex_registers + 0xC0, 0x00000100);
653f11c7f63SJim Harris 
654f11c7f63SJim Harris    scic_sds_controller_lex_status_read_fence(this_controller);
655f11c7f63SJim Harris 
656f11c7f63SJim Harris    // 8. Release LEX SCU Reset
657f11c7f63SJim Harris    lex_register_write(
658f11c7f63SJim Harris       this_controller, this_controller->lex_registers + 0xC0, 0x00000000);
659f11c7f63SJim Harris 
660f11c7f63SJim Harris    scic_sds_controller_lex_status_read_fence(this_controller);
661f11c7f63SJim Harris 
662f11c7f63SJim Harris #if !defined(DISABLE_INTERRUPTS)
663f11c7f63SJim Harris    // 8a. Set legacy interrupts (SCU INTx to PCI-x INTA)
664f11c7f63SJim Harris    lex_register_write(
665f11c7f63SJim Harris       this_controller, this_controller->lex_registers + 0xC0, 0x00000800);
666f11c7f63SJim Harris 
667f11c7f63SJim Harris    scic_sds_controller_lex_status_read_fence(this_controller);
668f11c7f63SJim Harris #endif
669f11c7f63SJim Harris 
670f11c7f63SJim Harris #if 0
671f11c7f63SJim Harris    // 9. Override TXOLVL
672f11c7f63SJim Harris    //write to lex_ctrl
673f11c7f63SJim Harris    lex_register_write(
674f11c7f63SJim Harris       this_controller, this_controller->lex_registers + 0xC0, 0x27800000);
675f11c7f63SJim Harris #endif
676f11c7f63SJim Harris 
677f11c7f63SJim Harris    // 10. Release PHY-A & PHY-B Resets
678f11c7f63SJim Harris    lex_register_write(
679f11c7f63SJim Harris       this_controller, this_controller->lex_registers + 0x28, 0x0000FF77);
680f11c7f63SJim Harris 
681f11c7f63SJim Harris    lex_register_write(
682f11c7f63SJim Harris       this_controller, this_controller->lex_registers + 0x28, 0x0000FF55);
683f11c7f63SJim Harris 
684f11c7f63SJim Harris    lex_register_write(
685f11c7f63SJim Harris       this_controller, this_controller->lex_registers + 0x28, 0x0000FF11);
686f11c7f63SJim Harris 
687f11c7f63SJim Harris    lex_register_write(
688f11c7f63SJim Harris       this_controller, this_controller->lex_registers + 0x28, 0x0000FF00);
689f11c7f63SJim Harris 
690f11c7f63SJim Harris    lex_register_write(
691f11c7f63SJim Harris       this_controller, this_controller->lex_registers + 0x28, 0x0003FF00);
692f11c7f63SJim Harris }
693f11c7f63SJim Harris #endif // ARLINGTON_BUILD
694f11c7f63SJim Harris 
695f11c7f63SJim Harris // ---------------------------------------------------------------------------
696f11c7f63SJim Harris 
697f11c7f63SJim Harris #ifdef ARLINGTON_BUILD
698f11c7f63SJim Harris /**
699f11c7f63SJim Harris  * This method enables chipwatch on the arlington board
700f11c7f63SJim Harris  *
701f11c7f63SJim Harris  * @param[in] this_controller
702f11c7f63SJim Harris  */
scic_sds_controller_enable_chipwatch(SCIC_SDS_CONTROLLER_T * this_controller)703f11c7f63SJim Harris void scic_sds_controller_enable_chipwatch(
704f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
705f11c7f63SJim Harris )
706f11c7f63SJim Harris {
707f11c7f63SJim Harris    lex_register_write(
708f11c7f63SJim Harris       this_controller, this_controller->lex_registers + 0x88, 0x09090909);
709f11c7f63SJim Harris 
710f11c7f63SJim Harris    lex_register_write(
711f11c7f63SJim Harris       this_controller, this_controller->lex_registers + 0x8C, 0xcac9c862);
712f11c7f63SJim Harris }
713f11c7f63SJim Harris #endif
714f11c7f63SJim Harris 
715f11c7f63SJim Harris /**
716f11c7f63SJim Harris  * This macro is used to delay between writes to the AFE registers
717f11c7f63SJim Harris  * during AFE initialization.
718f11c7f63SJim Harris  */
719f11c7f63SJim Harris #define AFE_REGISTER_WRITE_DELAY 10
720f11c7f63SJim Harris 
721f11c7f63SJim Harris /**
722f11c7f63SJim Harris  * Initialize the AFE for this phy index.
723f11c7f63SJim Harris  *
724f11c7f63SJim Harris  * @todo We need to read the AFE setup from the OEM parameters
725f11c7f63SJim Harris  *
726f11c7f63SJim Harris  * @param[in] this_controller
727f11c7f63SJim Harris  *
728f11c7f63SJim Harris  * @return none
729f11c7f63SJim Harris  */
730f11c7f63SJim Harris #if defined(ARLINGTON_BUILD)
scic_sds_controller_afe_initialization(SCIC_SDS_CONTROLLER_T * this_controller)731f11c7f63SJim Harris void scic_sds_controller_afe_initialization(
732f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
733f11c7f63SJim Harris )
734f11c7f63SJim Harris {
735f11c7f63SJim Harris    // 1. Establish Power
736f11c7f63SJim Harris    //       Hold Bias, PLL, and RX TX in reset and powerdown
737f11c7f63SJim Harris    //       pe_afe0_rst_n = 0
738f11c7f63SJim Harris    //       pe_afe0_txpdn0,1,2,3 = 1
739f11c7f63SJim Harris    //       pe_afe0_rxpdn0,1,2,3 = 1
740f11c7f63SJim Harris    //       pe_afe0_txrst0,1,2,3_n = 0
741f11c7f63SJim Harris    //       pe_afe0_rxrst0,1,2,3_n = 0
742f11c7f63SJim Harris    //       wait 1us
743f11c7f63SJim Harris    //       pe_afe0_rst_n = 1
744f11c7f63SJim Harris    //       wait 1us
745f11c7f63SJim Harris    scu_afe_register_write(
746f11c7f63SJim Harris       this_controller, afe_pll_control, 0x00247506);
747f11c7f63SJim Harris 
748f11c7f63SJim Harris    // 2. Write 0x00000000 to AFE XCVR Ctrl2
749f11c7f63SJim Harris    scu_afe_register_write(
750f11c7f63SJim Harris       this_controller, afe_dfx_transceiver_status_clear, 0x00000000);
751f11c7f63SJim Harris 
752f11c7f63SJim Harris    // 3. afe0_override_en = 0
753f11c7f63SJim Harris    //    afe0_pll_dis_override = 0
754f11c7f63SJim Harris    //    afe0_tx_rst_override = 0
755f11c7f63SJim Harris    //    afe0_pll_dis = 1
756f11c7f63SJim Harris    //    pe_afe0_txrate = 01
757f11c7f63SJim Harris    //    pe_afe0_rxrate = 01
758f11c7f63SJim Harris    //    pe_afe0_txdis = 11
759f11c7f63SJim Harris    //    pe_afe0_txoob = 1
760f11c7f63SJim Harris    //    pe_afe0_txovlv = 9'b001110000
761f11c7f63SJim Harris    scu_afe_register_write(
762f11c7f63SJim Harris       this_controller, afe_transceiver_control0[0], 0x0700141e);
763f11c7f63SJim Harris 
764f11c7f63SJim Harris    // 4. Configure PLL Unit
765f11c7f63SJim Harris    //    Write 0x00200506 to AFE PLL Ctrl Register 0
766f11c7f63SJim Harris    scu_afe_register_write(this_controller, afe_pll_control,     0x00200506);
767f11c7f63SJim Harris    scu_afe_register_write(this_controller, afe_pll_dfx_control, 0x10000080);
768f11c7f63SJim Harris 
769f11c7f63SJim Harris    // 5. Configure Bias Unit
770f11c7f63SJim Harris    scu_afe_register_write(this_controller, afe_bias_control[0], 0x00124814);
771f11c7f63SJim Harris    scu_afe_register_write(this_controller, afe_bias_control[1], 0x24900000);
772f11c7f63SJim Harris 
773f11c7f63SJim Harris    // 6. Configure Transceiver Units
774f11c7f63SJim Harris    scu_afe_register_write(
775f11c7f63SJim Harris       this_controller, afe_transceiver_control0[0], 0x0702941e);
776f11c7f63SJim Harris 
777f11c7f63SJim Harris    scu_afe_register_write(
778f11c7f63SJim Harris       this_controller, afe_transceiver_control1[0], 0x0000000a);
779f11c7f63SJim Harris 
780f11c7f63SJim Harris    // 7. Configure RX Units
781f11c7f63SJim Harris    scu_afe_register_write(
782f11c7f63SJim Harris       this_controller, afe_transceiver_equalization_control[0], 0x00ba2223);
783f11c7f63SJim Harris 
784f11c7f63SJim Harris    scu_afe_register_write(
785f11c7f63SJim Harris       this_controller, reserved_0028_003c[2], 0x00000000);
786f11c7f63SJim Harris 
787f11c7f63SJim Harris    // 8. Configure TX Units
788f11c7f63SJim Harris    scu_afe_register_write(
789f11c7f63SJim Harris       this_controller, afe_dfx_transmit_control_register[0], 0x03815428);
790f11c7f63SJim Harris 
791f11c7f63SJim Harris    // 9. Transfer control to PE signals
792f11c7f63SJim Harris    scu_afe_register_write(
793f11c7f63SJim Harris       this_controller, afe_dfx_transceiver_status_clear, 0x00000010);
794f11c7f63SJim Harris 
795f11c7f63SJim Harris    // 10. Release PLL Powerdown
796f11c7f63SJim Harris    scu_afe_register_write(this_controller, afe_pll_control, 0x00200504);
797f11c7f63SJim Harris 
798f11c7f63SJim Harris    // 11. Release PLL Reset
799f11c7f63SJim Harris    scu_afe_register_write(this_controller, afe_pll_control, 0x00200505);
800f11c7f63SJim Harris 
801f11c7f63SJim Harris    // 12. Wait for PLL to Lock
802f11c7f63SJim Harris    // (afe0_comm_sta [1:0] should go to 1'b11, and
803f11c7f63SJim Harris    //                [5:2] is 0x5, 0x6, 0x7, 0x8, or 0x9
804f11c7f63SJim Harris    scu_afe_register_write(this_controller, afe_pll_control, 0x00200501);
805f11c7f63SJim Harris 
806f11c7f63SJim Harris    while ((scu_afe_register_read(this_controller, afe_common_status) & 0x03) != 0x03)
807f11c7f63SJim Harris    {
808f11c7f63SJim Harris       // Give time for the PLLs to lock
809f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
810f11c7f63SJim Harris    }
811f11c7f63SJim Harris 
812f11c7f63SJim Harris    // 13. pe_afe0_rxpdn0 = 0
813f11c7f63SJim Harris    //     pe_afe0_rxrst0 = 1
814f11c7f63SJim Harris    //     pe_afe0_txrst0_n = 1
815f11c7f63SJim Harris    //     pe_afe_txoob0_n = 0
816f11c7f63SJim Harris    scu_afe_register_write(
817f11c7f63SJim Harris       this_controller, afe_transceiver_control0[0], 0x07028c11);
818f11c7f63SJim Harris }
819f11c7f63SJim Harris 
820f11c7f63SJim Harris #elif defined(PLEASANT_RIDGE_BUILD)
821f11c7f63SJim Harris 
scic_sds_controller_afe_initialization(SCIC_SDS_CONTROLLER_T * this_controller)822f11c7f63SJim Harris void scic_sds_controller_afe_initialization(
823f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
824f11c7f63SJim Harris )
825f11c7f63SJim Harris {
826f11c7f63SJim Harris    U32 afe_status;
827f11c7f63SJim Harris    U32 phy_id;
828f11c7f63SJim Harris 
829f11c7f63SJim Harris #if defined(SPREADSHEET_AFE_SETTINGS)
830f11c7f63SJim Harris    // Clear DFX Status registers
831f11c7f63SJim Harris    scu_afe_register_write(
832f11c7f63SJim Harris       this_controller, afe_dfx_master_control0, 0x0000000f);
833f11c7f63SJim Harris    // Configure bias currents to normal
834f11c7f63SJim Harris    scu_afe_register_write(
835f11c7f63SJim Harris       this_controller, afe_bias_control, 0x0000aa00);
836f11c7f63SJim Harris    // Enable PLL
837f11c7f63SJim Harris    scu_afe_register_write(
838f11c7f63SJim Harris       this_controller, afe_pll_control0, 0x80000908);
839f11c7f63SJim Harris 
840f11c7f63SJim Harris    // Wait for the PLL to lock
841f11c7f63SJim Harris    do
842f11c7f63SJim Harris    {
843f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
844f11c7f63SJim Harris       afe_status = scu_afe_register_read(
845f11c7f63SJim Harris                      this_controller, afe_common_block_status);
846f11c7f63SJim Harris    }
847f11c7f63SJim Harris    while((afe_status & 0x00001000) == 0);
848f11c7f63SJim Harris 
849f11c7f63SJim Harris    for (phy_id = 0; phy_id < SCI_MAX_PHYS; phy_id++)
850f11c7f63SJim Harris    {
851f11c7f63SJim Harris       // Initialize transceiver channels
852f11c7f63SJim Harris       scu_afe_register_write(
853f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_channel_control, 0x00000157);
854f11c7f63SJim Harris       // Configure transceiver modes
855f11c7f63SJim Harris       scu_afe_register_write(
856f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x38016d1a);
857f11c7f63SJim Harris       // Configure receiver parameters
858f11c7f63SJim Harris       scu_afe_register_write(
859f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control1, 0x01501014);
860f11c7f63SJim Harris       // Configure transmitter parameters
861f11c7f63SJim Harris       scu_afe_register_write(
862f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_tx_control, 0x00000000);
863f11c7f63SJim Harris       // Configure transmitter equalization
864f11c7f63SJim Harris       scu_afe_register_write(
865f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control0, 0x000bdd08);
866f11c7f63SJim Harris       scu_afe_register_write(
867f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control1, 0x000ffc00);
868f11c7f63SJim Harris       scu_afe_register_write(
869f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control2, 0x000b7c09);
870f11c7f63SJim Harris       scu_afe_register_write(
871f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control3, 0x000afc6e);
872f11c7f63SJim Harris       // Configure transmitter SSC parameters
873f11c7f63SJim Harris       scu_afe_register_write(
874f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_tx_ssc_control, 0x00000000);
875f11c7f63SJim Harris       // Configure receiver parameters
876f11c7f63SJim Harris       scu_afe_register_write(
877f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_rx_ssc_control0, 0x3208903f);
878f11c7f63SJim Harris 
879f11c7f63SJim Harris       // Start power on sequence
880f11c7f63SJim Harris       // Enable bias currents to transceivers and wait 200ns
881f11c7f63SJim Harris       scu_afe_register_write(
882f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_channel_control, 0x00000154);
883f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
884f11c7f63SJim Harris       // Take receiver out of power down and wait 200ns
885f11c7f63SJim Harris       scu_afe_register_write(
886f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x3801611a);
887f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
888f11c7f63SJim Harris       // Take receiver out of reset and wait 200ns
889f11c7f63SJim Harris       scu_afe_register_write(
890f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x3801631a);
891f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
892f11c7f63SJim Harris       // Take transmitter out of power down and wait 200ns
893f11c7f63SJim Harris       scu_afe_register_write(
894f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x38016318);
895f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
896f11c7f63SJim Harris       // Take transmitter out of reset and wait 200ns
897f11c7f63SJim Harris       scu_afe_register_write(
898f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x38016319);
899f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
900f11c7f63SJim Harris       // Take transmitter out of DC idle
901f11c7f63SJim Harris       scu_afe_register_write(
902f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x38016319);
903f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
904f11c7f63SJim Harris    }
905f11c7f63SJim Harris 
906f11c7f63SJim Harris    // Transfer control to the PEs
907f11c7f63SJim Harris    scu_afe_register_write(
908f11c7f63SJim Harris       this_controller, afe_dfx_master_control0, 0x00010f00);
909f11c7f63SJim Harris #else // !defined(SPREADSHEET_AFE_SETTINGS)
910f11c7f63SJim Harris    // These are the AFEE settings used by the SV group
911f11c7f63SJim Harris    // Clear DFX Status registers
912f11c7f63SJim Harris    scu_afe_register_write(
913f11c7f63SJim Harris       this_controller, afe_dfx_master_control0, 0x0081000f);
914f11c7f63SJim Harris    // Configure bias currents to normal
915f11c7f63SJim Harris    scu_afe_register_write(
916f11c7f63SJim Harris       this_controller, afe_bias_control, 0x0000aa00);
917f11c7f63SJim Harris    // Enable PLL
918f11c7f63SJim Harris    scu_afe_register_write(
919f11c7f63SJim Harris       this_controller, afe_pll_control0, 0x80000908);
920f11c7f63SJim Harris 
921f11c7f63SJim Harris    // Wait for the PLL to lock
922f11c7f63SJim Harris    // Note: this is done later in the SV shell script however this looks
923f11c7f63SJim Harris    //       like the location to do this since we have enabled the PLL.
924f11c7f63SJim Harris    do
925f11c7f63SJim Harris    {
926f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
927f11c7f63SJim Harris       afe_status = scu_afe_register_read(
928f11c7f63SJim Harris                      this_controller, afe_common_block_status);
929f11c7f63SJim Harris    }
930f11c7f63SJim Harris    while((afe_status & 0x00001000) == 0);
931f11c7f63SJim Harris 
932f11c7f63SJim Harris    // Make sure BIST is disabled
933f11c7f63SJim Harris    scu_afe_register_write(
934f11c7f63SJim Harris       this_controller, afe_dfx_master_control1, 0x00000000);
935f11c7f63SJim Harris    // Shorten SAS SNW lock time
936f11c7f63SJim Harris    scu_afe_register_write(
937f11c7f63SJim Harris       this_controller, afe_pmsn_master_control0, 0x7bd316ad);
938f11c7f63SJim Harris 
939f11c7f63SJim Harris    for (phy_id = 0; phy_id < SCI_MAX_PHYS; phy_id++)
940f11c7f63SJim Harris    {
941f11c7f63SJim Harris       // Initialize transceiver channels
942f11c7f63SJim Harris       scu_afe_register_write(
943f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_channel_control, 0x00000174);
944f11c7f63SJim Harris       // Configure SSC control
945f11c7f63SJim Harris       scu_afe_register_write(
946f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_tx_ssc_control, 0x00030000);
947f11c7f63SJim Harris       // Configure transceiver modes
948f11c7f63SJim Harris       scu_afe_register_write(
949f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x0000651a);
950f11c7f63SJim Harris       // Power up TX RX and RX OOB
951f11c7f63SJim Harris       scu_afe_register_write(
952f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x00006518);
953f11c7f63SJim Harris       // Enable RX OOB Detect
954f11c7f63SJim Harris       scu_afe_register_write(
955f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x00006518);
956f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
957f11c7f63SJim Harris       #if 0
958f11c7f63SJim Harris       // Configure transmitter parameters
959f11c7f63SJim Harris       scu_afe_register_write(
960f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_tx_control, 0x00000000);
961f11c7f63SJim Harris       // Configure transmitter equalization
962f11c7f63SJim Harris       scu_afe_register_write(
963f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control0, 0x000bdd08);
964f11c7f63SJim Harris       scu_afe_register_write(
965f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control1, 0x000ffc00);
966f11c7f63SJim Harris       scu_afe_register_write(
967f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control2, 0x000b7c09);
968f11c7f63SJim Harris       scu_afe_register_write(
969f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control3, 0x000afc6e);
970f11c7f63SJim Harris       // Configure transmitter SSC parameters
971f11c7f63SJim Harris       // Power up TX RX
972f11c7f63SJim Harris 
973f11c7f63SJim Harris       scu_afe_register_write(
974f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_channel_control, 0x00000154);
975f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
976f11c7f63SJim Harris 
977f11c7f63SJim Harris       // FFE = Max
978f11c7f63SJim Harris       scu_afe_register_write(
979f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_dfx_rx_control1, 0x00000080);
980f11c7f63SJim Harris       // DFE1-5 = small
981f11c7f63SJim Harris       scu_afe_register_write(
982f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_dfx_rx_control1, 0x01041042);
983f11c7f63SJim Harris       // Enable DFE/FFE and freeze
984f11c7f63SJim Harris       scu_afe_register_write(
985f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_rx_ssc_control0, 0x320891bf);
986f11c7f63SJim Harris       #endif
987f11c7f63SJim Harris       // Take receiver out of power down and wait 200ns
988f11c7f63SJim Harris       scu_afe_register_write(
989f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x00006118);
990f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
991f11c7f63SJim Harris       // TX Electrical Idle
992f11c7f63SJim Harris       scu_afe_register_write(
993f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x00006108);
994f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
995f11c7f63SJim Harris 
996f11c7f63SJim Harris       // Leave DFE/FFE on
997f11c7f63SJim Harris       scu_afe_register_write(
998f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_rx_ssc_control0, 0x0317108f);
999f11c7f63SJim Harris 
1000f11c7f63SJim Harris       // Configure receiver parameters
1001f11c7f63SJim Harris       scu_afe_register_write(
1002f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control1, 0x01e00021);
1003f11c7f63SJim Harris 
1004f11c7f63SJim Harris       // Bring RX out of reset
1005f11c7f63SJim Harris       scu_afe_register_write(
1006f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x00006109);
1007f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1008f11c7f63SJim Harris 
1009f11c7f63SJim Harris       scu_afe_register_write(
1010f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x00006009);
1011f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1012f11c7f63SJim Harris 
1013f11c7f63SJim Harris       scu_afe_register_write(
1014f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x00006209);
1015f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1016f11c7f63SJim Harris    }
1017f11c7f63SJim Harris 
1018f11c7f63SJim Harris    // Transfer control to the PEs
1019f11c7f63SJim Harris    scu_afe_register_write(
1020f11c7f63SJim Harris       this_controller, afe_dfx_master_control0, 0x00010f00);
1021f11c7f63SJim Harris #endif
1022f11c7f63SJim Harris }
1023f11c7f63SJim Harris 
1024f11c7f63SJim Harris #elif defined(PBG_HBA_A0_BUILD) || defined(PBG_HBA_A2_BUILD) || defined(PBG_HBA_BETA_BUILD) || defined(PBG_BUILD)
1025f11c7f63SJim Harris 
scic_sds_controller_afe_initialization(SCIC_SDS_CONTROLLER_T * this_controller)1026f11c7f63SJim Harris void scic_sds_controller_afe_initialization(
1027f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
1028f11c7f63SJim Harris )
1029f11c7f63SJim Harris {
1030f11c7f63SJim Harris    U32  afe_status;
1031f11c7f63SJim Harris    U32  phy_id;
1032f11c7f63SJim Harris    U8   cable_selection_mask;
1033f11c7f63SJim Harris 
1034f11c7f63SJim Harris    if (
1035f11c7f63SJim Harris          (this_controller->pci_revision != SCIC_SDS_PCI_REVISION_A0)
1036f11c7f63SJim Harris       && (this_controller->pci_revision != SCIC_SDS_PCI_REVISION_A2)
1037f11c7f63SJim Harris       && (this_controller->pci_revision != SCIC_SDS_PCI_REVISION_B0)
1038f11c7f63SJim Harris       && (this_controller->pci_revision != SCIC_SDS_PCI_REVISION_C0)
1039f11c7f63SJim Harris       && (this_controller->pci_revision != SCIC_SDS_PCI_REVISION_C1)
1040f11c7f63SJim Harris       )
1041f11c7f63SJim Harris    {
1042f11c7f63SJim Harris       // A programming bug has occurred if we are attempting to
1043f11c7f63SJim Harris       // support a PCI revision other than those listed.  Default
1044f11c7f63SJim Harris       // to B0, and attempt to limp along if it isn't B0.
1045f11c7f63SJim Harris       ASSERT(FALSE);
1046f11c7f63SJim Harris       this_controller->pci_revision = SCIC_SDS_PCI_REVISION_C1;
1047f11c7f63SJim Harris    }
1048f11c7f63SJim Harris 
1049f11c7f63SJim Harris    cable_selection_mask =
1050f11c7f63SJim Harris       this_controller->oem_parameters.sds1.controller.cable_selection_mask;
1051f11c7f63SJim Harris 
1052f11c7f63SJim Harris    // These are the AFEE settings used by the SV group
1053f11c7f63SJim Harris    // Clear DFX Status registers
1054f11c7f63SJim Harris    scu_afe_register_write(
1055f11c7f63SJim Harris       this_controller, afe_dfx_master_control0, 0x0081000f);
1056f11c7f63SJim Harris    scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1057f11c7f63SJim Harris 
1058f11c7f63SJim Harris    if (
1059f11c7f63SJim Harris          (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_B0)
1060f11c7f63SJim Harris       || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C0)
1061f11c7f63SJim Harris       || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C1)
1062f11c7f63SJim Harris       )
1063f11c7f63SJim Harris    {
1064f11c7f63SJim Harris       // PM Rx Equalization Save, PM SPhy Rx Acknowledgement Timer, PM Stagger Timer
1065f11c7f63SJim Harris       scu_afe_register_write(
1066f11c7f63SJim Harris          this_controller, afe_pmsn_master_control2, 0x0007FFFF);
1067f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1068f11c7f63SJim Harris    }
1069f11c7f63SJim Harris 
1070f11c7f63SJim Harris    // Configure bias currents to normal
1071f11c7f63SJim Harris    if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A0)
1072f11c7f63SJim Harris       scu_afe_register_write(this_controller, afe_bias_control, 0x00005500);
1073f11c7f63SJim Harris    else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A2)
1074f11c7f63SJim Harris       scu_afe_register_write(this_controller, afe_bias_control, 0x00005A00);
1075f11c7f63SJim Harris    else if (  (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_B0)
1076f11c7f63SJim Harris            || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C0) )
1077f11c7f63SJim Harris       scu_afe_register_write(this_controller, afe_bias_control, 0x00005F00);
1078f11c7f63SJim Harris    else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C1)
1079f11c7f63SJim Harris       scu_afe_register_write(this_controller, afe_bias_control, 0x00005500);
1080453130d9SPedro F. Giffuni    // For C0 the AFE BIAS Control is unchanged
1081f11c7f63SJim Harris 
1082f11c7f63SJim Harris    scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1083f11c7f63SJim Harris 
1084f11c7f63SJim Harris       // Enable PLL
1085f11c7f63SJim Harris    if (  (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A0)
1086f11c7f63SJim Harris       || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A2) )
1087f11c7f63SJim Harris    {
1088f11c7f63SJim Harris       scu_afe_register_write(this_controller, afe_pll_control0, 0x80040908);
1089f11c7f63SJim Harris    }
1090f11c7f63SJim Harris    else if (  (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_B0)
1091f11c7f63SJim Harris            || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C0) )
1092f11c7f63SJim Harris    {
1093f11c7f63SJim Harris       scu_afe_register_write(this_controller, afe_pll_control0, 0x80040A08);
1094f11c7f63SJim Harris    }
1095f11c7f63SJim Harris    else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C1)
1096f11c7f63SJim Harris    {
1097f11c7f63SJim Harris       scu_afe_register_write(this_controller, afe_pll_control0, 0x80000b08);
1098f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1099f11c7f63SJim Harris       scu_afe_register_write(this_controller, afe_pll_control0, 0x00000b08);
1100f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1101f11c7f63SJim Harris       scu_afe_register_write(this_controller, afe_pll_control0, 0x80000b08);
1102f11c7f63SJim Harris    }
1103f11c7f63SJim Harris 
1104f11c7f63SJim Harris    scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1105f11c7f63SJim Harris 
1106f11c7f63SJim Harris    // Wait for the PLL to lock
1107f11c7f63SJim Harris    // Note: this is done later in the SV shell script however this looks
1108f11c7f63SJim Harris    //       like the location to do this since we have enabled the PLL.
1109f11c7f63SJim Harris    do
1110f11c7f63SJim Harris    {
1111f11c7f63SJim Harris       afe_status = scu_afe_register_read(
1112f11c7f63SJim Harris                       this_controller, afe_common_block_status);
1113f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1114f11c7f63SJim Harris    }
1115f11c7f63SJim Harris    while((afe_status & 0x00001000) == 0);
1116f11c7f63SJim Harris 
1117f11c7f63SJim Harris    if (  (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A0)
1118f11c7f63SJim Harris       || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A2) )
1119f11c7f63SJim Harris    {
1120f11c7f63SJim Harris       // Shorten SAS SNW lock time (RxLock timer value from 76 us to 50 us)
1121f11c7f63SJim Harris       scu_afe_register_write(
1122f11c7f63SJim Harris          this_controller, afe_pmsn_master_control0, 0x7bcc96ad);
1123f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1124f11c7f63SJim Harris    }
1125f11c7f63SJim Harris 
1126f11c7f63SJim Harris    for (phy_id = 0; phy_id < SCI_MAX_PHYS; phy_id++)
1127f11c7f63SJim Harris    {
1128f11c7f63SJim Harris       U8 cable_length_long   = (cable_selection_mask >> phy_id) & 1;
1129f11c7f63SJim Harris       U8 cable_length_medium = (cable_selection_mask >> (phy_id + 4)) & 1;
1130f11c7f63SJim Harris 
1131f11c7f63SJim Harris       if (  (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A0)
1132f11c7f63SJim Harris          || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A2) )
1133f11c7f63SJim Harris       {
1134f11c7f63SJim Harris          // All defaults, except the Receive Word Alignament/Comma Detect
1135f11c7f63SJim Harris          // Enable....(0xe800)
1136f11c7f63SJim Harris          scu_afe_register_write(
1137f11c7f63SJim Harris             this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x00004512
1138f11c7f63SJim Harris          );
1139f11c7f63SJim Harris          scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1140f11c7f63SJim Harris 
1141f11c7f63SJim Harris          scu_afe_register_write(
1142f11c7f63SJim Harris             this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control1, 0x0050100F
1143f11c7f63SJim Harris          );
1144f11c7f63SJim Harris          scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1145f11c7f63SJim Harris       }
1146f11c7f63SJim Harris       else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_B0)
1147f11c7f63SJim Harris       {
1148f11c7f63SJim Harris          // Configure transmitter SSC parameters
1149f11c7f63SJim Harris          scu_afe_register_write(
1150f11c7f63SJim Harris             this_controller, scu_afe_xcvr[phy_id].afe_tx_ssc_control, 0x00030000
1151f11c7f63SJim Harris          );
1152f11c7f63SJim Harris          scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1153f11c7f63SJim Harris       }
1154f11c7f63SJim Harris       else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C0)
1155f11c7f63SJim Harris       {
1156f11c7f63SJim Harris          // Configure transmitter SSC parameters
1157f11c7f63SJim Harris          scu_afe_register_write(
1158f11c7f63SJim Harris             this_controller, scu_afe_xcvr[phy_id].afe_tx_ssc_control, 0x00010202
1159f11c7f63SJim Harris          );
1160f11c7f63SJim Harris          scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1161f11c7f63SJim Harris 
1162f11c7f63SJim Harris          // All defaults, except the Receive Word Alignament/Comma Detect
1163f11c7f63SJim Harris          // Enable....(0xe800)
1164f11c7f63SJim Harris          scu_afe_register_write(
1165f11c7f63SJim Harris             this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x00014500
1166f11c7f63SJim Harris          );
1167f11c7f63SJim Harris          scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1168f11c7f63SJim Harris       }
1169f11c7f63SJim Harris       else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C1)
1170f11c7f63SJim Harris       {
1171f11c7f63SJim Harris          // Configure transmitter SSC parameters
1172f11c7f63SJim Harris          scu_afe_register_write(
1173f11c7f63SJim Harris             this_controller, scu_afe_xcvr[phy_id].afe_tx_ssc_control, 0x00010202
1174f11c7f63SJim Harris          );
1175f11c7f63SJim Harris          scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1176f11c7f63SJim Harris 
1177f11c7f63SJim Harris          // All defaults, except the Receive Word Alignament/Comma Detect
1178f11c7f63SJim Harris          // Enable....(0xe800)
1179f11c7f63SJim Harris          scu_afe_register_write(
1180f11c7f63SJim Harris             this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x0001C500
1181f11c7f63SJim Harris          );
1182f11c7f63SJim Harris          scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1183f11c7f63SJim Harris       }
1184f11c7f63SJim Harris       // Power up TX and RX out from power down (PWRDNTX and PWRDNRX)
1185f11c7f63SJim Harris       // & increase TX int & ext bias 20%....(0xe85c)
1186f11c7f63SJim Harris       if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A0)
1187f11c7f63SJim Harris       {
1188f11c7f63SJim Harris          scu_afe_register_write(
1189f11c7f63SJim Harris             this_controller,
1190f11c7f63SJim Harris             scu_afe_xcvr[phy_id].afe_channel_control,
1191f11c7f63SJim Harris             0x000003D4
1192f11c7f63SJim Harris          );
1193f11c7f63SJim Harris       }
1194f11c7f63SJim Harris       else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A2)
1195f11c7f63SJim Harris       {
1196f11c7f63SJim Harris          scu_afe_register_write(
1197f11c7f63SJim Harris             this_controller,
1198f11c7f63SJim Harris             scu_afe_xcvr[phy_id].afe_channel_control,
1199f11c7f63SJim Harris             0x000003F0
1200f11c7f63SJim Harris          );
1201f11c7f63SJim Harris       }
1202f11c7f63SJim Harris       else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_B0)
1203f11c7f63SJim Harris       {
1204f11c7f63SJim Harris          // Power down TX and RX (PWRDNTX and PWRDNRX)
1205f11c7f63SJim Harris          scu_afe_register_write(
1206f11c7f63SJim Harris             this_controller,
1207f11c7f63SJim Harris             scu_afe_xcvr[phy_id].afe_channel_control,
1208f11c7f63SJim Harris             0x000003d7
1209f11c7f63SJim Harris          );
1210f11c7f63SJim Harris 
1211f11c7f63SJim Harris          scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1212f11c7f63SJim Harris 
1213f11c7f63SJim Harris          // Power up TX and RX out from power down (PWRDNTX and PWRDNRX)
1214f11c7f63SJim Harris          // & increase TX int & ext bias 20%....(0xe85c)
1215f11c7f63SJim Harris          scu_afe_register_write(
1216f11c7f63SJim Harris             this_controller,
1217f11c7f63SJim Harris             scu_afe_xcvr[phy_id].afe_channel_control,
1218f11c7f63SJim Harris             0x000003d4
1219f11c7f63SJim Harris          );
1220f11c7f63SJim Harris       }
1221f11c7f63SJim Harris       else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C0)
1222f11c7f63SJim Harris       {
1223f11c7f63SJim Harris          scu_afe_register_write(
1224f11c7f63SJim Harris             this_controller,
1225f11c7f63SJim Harris             scu_afe_xcvr[phy_id].afe_channel_control,
1226f11c7f63SJim Harris             0x000001e7
1227f11c7f63SJim Harris          );
1228f11c7f63SJim Harris 
1229f11c7f63SJim Harris          scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1230f11c7f63SJim Harris 
1231f11c7f63SJim Harris          // Power up TX and RX out from power down (PWRDNTX and PWRDNRX)
1232f11c7f63SJim Harris          // & increase TX int & ext bias 20%....(0xe85c)
1233f11c7f63SJim Harris          scu_afe_register_write(
1234f11c7f63SJim Harris             this_controller,
1235f11c7f63SJim Harris             scu_afe_xcvr[phy_id].afe_channel_control,
1236f11c7f63SJim Harris             0x000001e4
1237f11c7f63SJim Harris          );
1238f11c7f63SJim Harris       }
1239f11c7f63SJim Harris       else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C1)
1240f11c7f63SJim Harris       {
1241f11c7f63SJim Harris          scu_afe_register_write(
1242f11c7f63SJim Harris             this_controller,
1243f11c7f63SJim Harris             scu_afe_xcvr[phy_id].afe_channel_control,
1244f11c7f63SJim Harris             cable_length_long   ? 0x000002F7 :
1245f11c7f63SJim Harris             cable_length_medium ? 0x000001F7 : 0x000001F7
1246f11c7f63SJim Harris          );
1247f11c7f63SJim Harris 
1248f11c7f63SJim Harris          scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1249f11c7f63SJim Harris 
1250f11c7f63SJim Harris          // Power up TX and RX out from power down (PWRDNTX and PWRDNRX)
1251f11c7f63SJim Harris          // & increase TX int & ext bias 20%....(0xe85c)
1252f11c7f63SJim Harris          scu_afe_register_write(
1253f11c7f63SJim Harris             this_controller,
1254f11c7f63SJim Harris             scu_afe_xcvr[phy_id].afe_channel_control,
1255f11c7f63SJim Harris             cable_length_long   ? 0x000002F4 :
1256f11c7f63SJim Harris             cable_length_medium ? 0x000001F4 : 0x000001F4
1257f11c7f63SJim Harris          );
1258f11c7f63SJim Harris       }
1259f11c7f63SJim Harris 
1260f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1261f11c7f63SJim Harris 
1262f11c7f63SJim Harris       if (  (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A0)
1263f11c7f63SJim Harris          || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A2) )
1264f11c7f63SJim Harris       {
1265f11c7f63SJim Harris          // Enable TX equalization (0xe824)
1266f11c7f63SJim Harris          scu_afe_register_write(
1267f11c7f63SJim Harris             this_controller,
1268f11c7f63SJim Harris             scu_afe_xcvr[phy_id].afe_tx_control,
1269f11c7f63SJim Harris             0x00040000
1270f11c7f63SJim Harris          );
1271f11c7f63SJim Harris          scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1272f11c7f63SJim Harris       }
1273f11c7f63SJim Harris 
1274f11c7f63SJim Harris       if (  (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A0)
1275f11c7f63SJim Harris          || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A2)
1276f11c7f63SJim Harris          || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_B0) )
1277f11c7f63SJim Harris       {
1278f11c7f63SJim Harris          // RDPI=0x0(RX Power On), RXOOBDETPDNC=0x0, TPD=0x0(TX Power On),
1279f11c7f63SJim Harris          // RDD=0x0(RX Detect Enabled) ....(0xe800)
1280f11c7f63SJim Harris          scu_afe_register_write(
1281f11c7f63SJim Harris             this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x00004100);
1282f11c7f63SJim Harris          scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1283f11c7f63SJim Harris       }
1284f11c7f63SJim Harris       else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C0)
1285f11c7f63SJim Harris       {
1286f11c7f63SJim Harris          scu_afe_register_write(
1287f11c7f63SJim Harris             this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x00014100);
1288f11c7f63SJim Harris          scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1289f11c7f63SJim Harris       }
1290f11c7f63SJim Harris       else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C1)
1291f11c7f63SJim Harris       {
1292f11c7f63SJim Harris          scu_afe_register_write(
1293f11c7f63SJim Harris             this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control0, 0x0001c100);
1294f11c7f63SJim Harris          scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1295f11c7f63SJim Harris       }
1296f11c7f63SJim Harris 
1297f11c7f63SJim Harris       // Leave DFE/FFE on
1298f11c7f63SJim Harris       if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A0)
1299f11c7f63SJim Harris       {
1300f11c7f63SJim Harris          scu_afe_register_write(
1301f11c7f63SJim Harris             this_controller,
1302f11c7f63SJim Harris             scu_afe_xcvr[phy_id].afe_rx_ssc_control0,
1303f11c7f63SJim Harris             0x3F09983F
1304f11c7f63SJim Harris          );
1305f11c7f63SJim Harris       }
1306f11c7f63SJim Harris       else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A2)
1307f11c7f63SJim Harris       {
1308f11c7f63SJim Harris          scu_afe_register_write(
1309f11c7f63SJim Harris             this_controller,
1310f11c7f63SJim Harris             scu_afe_xcvr[phy_id].afe_rx_ssc_control0,
1311f11c7f63SJim Harris             0x3F11103F
1312f11c7f63SJim Harris          );
1313f11c7f63SJim Harris       }
1314f11c7f63SJim Harris       else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_B0)
1315f11c7f63SJim Harris       {
1316f11c7f63SJim Harris          scu_afe_register_write(
1317f11c7f63SJim Harris             this_controller,
1318f11c7f63SJim Harris             scu_afe_xcvr[phy_id].afe_rx_ssc_control0,
1319f11c7f63SJim Harris             0x3F11103F
1320f11c7f63SJim Harris          );
1321f11c7f63SJim Harris          scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1322f11c7f63SJim Harris 
1323f11c7f63SJim Harris          // Enable TX equalization (0xe824)
1324f11c7f63SJim Harris          scu_afe_register_write(
1325f11c7f63SJim Harris             this_controller, scu_afe_xcvr[phy_id].afe_tx_control, 0x00040000);
1326f11c7f63SJim Harris       }
1327f11c7f63SJim Harris       else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C0)
1328f11c7f63SJim Harris       {
1329f11c7f63SJim Harris          scu_afe_register_write(
1330f11c7f63SJim Harris             this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control1, 0x01400c0f);
1331f11c7f63SJim Harris          scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1332f11c7f63SJim Harris 
1333f11c7f63SJim Harris          scu_afe_register_write(
1334f11c7f63SJim Harris             this_controller, scu_afe_xcvr[phy_id].afe_rx_ssc_control0, 0x3f6f103f);
1335f11c7f63SJim Harris          scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1336f11c7f63SJim Harris 
1337f11c7f63SJim Harris          // Enable TX equalization (0xe824)
1338f11c7f63SJim Harris          scu_afe_register_write(
1339f11c7f63SJim Harris             this_controller, scu_afe_xcvr[phy_id].afe_tx_control, 0x00040000);
1340f11c7f63SJim Harris       }
1341f11c7f63SJim Harris       else if (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_C1)
1342f11c7f63SJim Harris       {
1343f11c7f63SJim Harris          scu_afe_register_write(
1344f11c7f63SJim Harris             this_controller, scu_afe_xcvr[phy_id].afe_xcvr_control1,
1345f11c7f63SJim Harris             cable_length_long   ? 0x01500C0C :
1346f11c7f63SJim Harris             cable_length_medium ? 0x01400C0D : 0x02400C0D
1347f11c7f63SJim Harris          );
1348f11c7f63SJim Harris          scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1349f11c7f63SJim Harris 
1350f11c7f63SJim Harris          scu_afe_register_write(
1351f11c7f63SJim Harris             this_controller, scu_afe_xcvr[phy_id].afe_dfx_rx_control1, 0x000003e0);
1352f11c7f63SJim Harris          scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1353f11c7f63SJim Harris 
1354f11c7f63SJim Harris          scu_afe_register_write(
1355f11c7f63SJim Harris             this_controller, scu_afe_xcvr[phy_id].afe_rx_ssc_control0,
1356f11c7f63SJim Harris             cable_length_long   ? 0x33091C1F :
1357f11c7f63SJim Harris             cable_length_medium ? 0x3315181F : 0x2B17161F
1358f11c7f63SJim Harris          );
1359f11c7f63SJim Harris          scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1360f11c7f63SJim Harris 
1361f11c7f63SJim Harris          // Enable TX equalization (0xe824)
1362f11c7f63SJim Harris          scu_afe_register_write(
1363f11c7f63SJim Harris             this_controller, scu_afe_xcvr[phy_id].afe_tx_control, 0x00040000);
1364f11c7f63SJim Harris       }
1365f11c7f63SJim Harris 
1366f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1367f11c7f63SJim Harris 
1368f11c7f63SJim Harris       scu_afe_register_write(
1369f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control0,
1370f11c7f63SJim Harris          this_controller->oem_parameters.sds1.phys[phy_id].afe_tx_amp_control0
1371f11c7f63SJim Harris       );
1372f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1373f11c7f63SJim Harris 
1374f11c7f63SJim Harris       scu_afe_register_write(
1375f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control1,
1376f11c7f63SJim Harris          this_controller->oem_parameters.sds1.phys[phy_id].afe_tx_amp_control1
1377f11c7f63SJim Harris       );
1378f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1379f11c7f63SJim Harris 
1380f11c7f63SJim Harris       scu_afe_register_write(
1381f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control2,
1382f11c7f63SJim Harris          this_controller->oem_parameters.sds1.phys[phy_id].afe_tx_amp_control2
1383f11c7f63SJim Harris       );
1384f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1385f11c7f63SJim Harris 
1386f11c7f63SJim Harris       scu_afe_register_write(
1387f11c7f63SJim Harris          this_controller, scu_afe_xcvr[phy_id].afe_tx_amp_control3,
1388f11c7f63SJim Harris          this_controller->oem_parameters.sds1.phys[phy_id].afe_tx_amp_control3
1389f11c7f63SJim Harris       );
1390f11c7f63SJim Harris       scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1391f11c7f63SJim Harris    }
1392f11c7f63SJim Harris 
1393f11c7f63SJim Harris    // Transfer control to the PEs
1394f11c7f63SJim Harris    scu_afe_register_write(
1395f11c7f63SJim Harris       this_controller, afe_dfx_master_control0, 0x00010f00);
1396f11c7f63SJim Harris    scic_cb_stall_execution(AFE_REGISTER_WRITE_DELAY);
1397f11c7f63SJim Harris }
1398f11c7f63SJim Harris #else
1399f11c7f63SJim Harris    #error "Unsupported board type"
1400f11c7f63SJim Harris #endif
1401f11c7f63SJim Harris 
1402f11c7f63SJim Harris //****************************************************************************-
1403f11c7f63SJim Harris //* SCIC SDS Controller Internal Start/Stop Routines
1404f11c7f63SJim Harris //****************************************************************************-
1405f11c7f63SJim Harris 
1406f11c7f63SJim Harris 
1407f11c7f63SJim Harris /**
1408f11c7f63SJim Harris  * @brief This method will attempt to transition into the ready state
1409f11c7f63SJim Harris  *        for the controller and indicate that the controller start
1410f11c7f63SJim Harris  *        operation has completed if all criteria are met.
1411f11c7f63SJim Harris  *
1412f11c7f63SJim Harris  * @param[in,out] this_controller This parameter indicates the controller
1413f11c7f63SJim Harris  *                object for which to transition to ready.
1414f11c7f63SJim Harris  * @param[in]     status This parameter indicates the status value to be
1415f11c7f63SJim Harris  *                pass into the call to scic_cb_controller_start_complete().
1416f11c7f63SJim Harris  *
1417f11c7f63SJim Harris  * @return none.
1418f11c7f63SJim Harris  */
1419f11c7f63SJim Harris static
scic_sds_controller_transition_to_ready(SCIC_SDS_CONTROLLER_T * this_controller,SCI_STATUS status)1420f11c7f63SJim Harris void scic_sds_controller_transition_to_ready(
1421f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller,
1422f11c7f63SJim Harris    SCI_STATUS             status
1423f11c7f63SJim Harris )
1424f11c7f63SJim Harris {
1425f11c7f63SJim Harris    SCIC_LOG_TRACE((
1426f11c7f63SJim Harris       sci_base_object_get_logger(this_controller),
1427f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
1428f11c7f63SJim Harris       "scic_sds_controller_transition_to_ready(0x%x, 0x%x) enter\n",
1429f11c7f63SJim Harris       this_controller, status
1430f11c7f63SJim Harris    ));
1431f11c7f63SJim Harris 
1432f11c7f63SJim Harris    if (this_controller->parent.state_machine.current_state_id
1433f11c7f63SJim Harris        == SCI_BASE_CONTROLLER_STATE_STARTING)
1434f11c7f63SJim Harris    {
1435f11c7f63SJim Harris       // We move into the ready state, because some of the phys/ports
1436f11c7f63SJim Harris       // may be up and operational.
1437f11c7f63SJim Harris       sci_base_state_machine_change_state(
1438f11c7f63SJim Harris          scic_sds_controller_get_base_state_machine(this_controller),
1439f11c7f63SJim Harris          SCI_BASE_CONTROLLER_STATE_READY
1440f11c7f63SJim Harris       );
1441f11c7f63SJim Harris 
1442f11c7f63SJim Harris       scic_cb_controller_start_complete(this_controller, status);
1443f11c7f63SJim Harris    }
1444f11c7f63SJim Harris }
1445f11c7f63SJim Harris 
1446f11c7f63SJim Harris /**
1447f11c7f63SJim Harris  * @brief This method is the general timeout handler for the controller.
1448f11c7f63SJim Harris  *        It will take the correct timetout action based on the current
1449f11c7f63SJim Harris  *        controller state
1450f11c7f63SJim Harris  *
1451f11c7f63SJim Harris  * @param[in] controller This parameter indicates the controller on which
1452f11c7f63SJim Harris  *            a timeout occurred.
1453f11c7f63SJim Harris  *
1454f11c7f63SJim Harris  * @return none
1455f11c7f63SJim Harris  */
scic_sds_controller_timeout_handler(SCI_CONTROLLER_HANDLE_T controller)1456f11c7f63SJim Harris void scic_sds_controller_timeout_handler(
1457f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller
1458f11c7f63SJim Harris )
1459f11c7f63SJim Harris {
1460f11c7f63SJim Harris    SCI_BASE_CONTROLLER_STATES current_state;
1461f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
1462f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
1463f11c7f63SJim Harris 
1464f11c7f63SJim Harris    current_state = sci_base_state_machine_get_state(
1465f11c7f63SJim Harris                       scic_sds_controller_get_base_state_machine(this_controller)
1466f11c7f63SJim Harris                    );
1467f11c7f63SJim Harris 
1468f11c7f63SJim Harris    if (current_state == SCI_BASE_CONTROLLER_STATE_STARTING)
1469f11c7f63SJim Harris    {
1470f11c7f63SJim Harris       scic_sds_controller_transition_to_ready(
1471f11c7f63SJim Harris          this_controller, SCI_FAILURE_TIMEOUT
1472f11c7f63SJim Harris       );
1473f11c7f63SJim Harris    }
1474f11c7f63SJim Harris    else if (current_state == SCI_BASE_CONTROLLER_STATE_STOPPING)
1475f11c7f63SJim Harris    {
1476f11c7f63SJim Harris       sci_base_state_machine_change_state(
1477f11c7f63SJim Harris          scic_sds_controller_get_base_state_machine(this_controller),
1478f11c7f63SJim Harris          SCI_BASE_CONTROLLER_STATE_FAILED
1479f11c7f63SJim Harris       );
1480f11c7f63SJim Harris 
1481f11c7f63SJim Harris       scic_cb_controller_stop_complete(controller, SCI_FAILURE_TIMEOUT);
1482f11c7f63SJim Harris    }
1483f11c7f63SJim Harris    else
1484f11c7f63SJim Harris    {
1485f11c7f63SJim Harris       /// @todo Now what do we want to do in this case?
1486f11c7f63SJim Harris       SCIC_LOG_ERROR((
1487f11c7f63SJim Harris          sci_base_object_get_logger(this_controller),
1488f11c7f63SJim Harris          SCIC_LOG_OBJECT_CONTROLLER,
1489f11c7f63SJim Harris          "Controller timer fired when controller was not in a state being timed.\n"
1490f11c7f63SJim Harris       ));
1491f11c7f63SJim Harris    }
1492f11c7f63SJim Harris }
1493f11c7f63SJim Harris 
1494f11c7f63SJim Harris /**
1495f11c7f63SJim Harris  * @brief
1496f11c7f63SJim Harris  *
1497f11c7f63SJim Harris  * @param[in] this_controller
1498f11c7f63SJim Harris  *
1499f11c7f63SJim Harris  * @return SCI_STATUS
1500f11c7f63SJim Harris  */
scic_sds_controller_stop_ports(SCIC_SDS_CONTROLLER_T * this_controller)1501f11c7f63SJim Harris SCI_STATUS scic_sds_controller_stop_ports(
1502f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
1503f11c7f63SJim Harris )
1504f11c7f63SJim Harris {
1505f11c7f63SJim Harris    U32        index;
1506f11c7f63SJim Harris    SCI_STATUS status;
1507f11c7f63SJim Harris    SCI_STATUS port_status;
1508f11c7f63SJim Harris 
1509f11c7f63SJim Harris    status = SCI_SUCCESS;
1510f11c7f63SJim Harris 
1511f11c7f63SJim Harris    for (index = 0; index < this_controller->logical_port_entries; index++)
1512f11c7f63SJim Harris    {
1513f11c7f63SJim Harris       port_status = this_controller->port_table[index].
1514f11c7f63SJim Harris          state_handlers->parent.stop_handler(&this_controller->port_table[index].parent);
1515f11c7f63SJim Harris       if (
1516f11c7f63SJim Harris             (port_status != SCI_SUCCESS)
1517f11c7f63SJim Harris          && (port_status != SCI_FAILURE_INVALID_STATE)
1518f11c7f63SJim Harris          )
1519f11c7f63SJim Harris       {
1520f11c7f63SJim Harris          status = SCI_FAILURE;
1521f11c7f63SJim Harris 
1522f11c7f63SJim Harris          SCIC_LOG_WARNING((
1523f11c7f63SJim Harris             sci_base_object_get_logger(this_controller),
1524f11c7f63SJim Harris             SCIC_LOG_OBJECT_CONTROLLER | SCIC_LOG_OBJECT_PORT,
1525f11c7f63SJim Harris             "Controller stop operation failed to stop port %d because of status %d.\n",
1526f11c7f63SJim Harris             this_controller->port_table[index].logical_port_index, port_status
1527f11c7f63SJim Harris          ));
1528f11c7f63SJim Harris       }
1529f11c7f63SJim Harris    }
1530f11c7f63SJim Harris 
1531f11c7f63SJim Harris    return status;
1532f11c7f63SJim Harris }
1533f11c7f63SJim Harris 
1534f11c7f63SJim Harris /**
1535f11c7f63SJim Harris  * @brief
1536f11c7f63SJim Harris  *
1537f11c7f63SJim Harris  * @param[in] this_controller
1538f11c7f63SJim Harris  */
1539f11c7f63SJim Harris static
scic_sds_controller_phy_timer_start(SCIC_SDS_CONTROLLER_T * this_controller)1540f11c7f63SJim Harris void scic_sds_controller_phy_timer_start(
1541f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
1542f11c7f63SJim Harris )
1543f11c7f63SJim Harris {
1544f11c7f63SJim Harris    scic_cb_timer_start(
1545f11c7f63SJim Harris       this_controller,
1546f11c7f63SJim Harris       this_controller->phy_startup_timer,
1547f11c7f63SJim Harris       SCIC_SDS_CONTROLLER_PHY_START_TIMEOUT
1548f11c7f63SJim Harris    );
1549f11c7f63SJim Harris 
1550f11c7f63SJim Harris    this_controller->phy_startup_timer_pending = TRUE;
1551f11c7f63SJim Harris }
1552f11c7f63SJim Harris 
1553f11c7f63SJim Harris /**
1554f11c7f63SJim Harris  * @brief
1555f11c7f63SJim Harris  *
1556f11c7f63SJim Harris  * @param[in] this_controller
1557f11c7f63SJim Harris  */
scic_sds_controller_phy_timer_stop(SCIC_SDS_CONTROLLER_T * this_controller)1558f11c7f63SJim Harris void scic_sds_controller_phy_timer_stop(
1559f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
1560f11c7f63SJim Harris )
1561f11c7f63SJim Harris {
1562f11c7f63SJim Harris    scic_cb_timer_stop(
1563f11c7f63SJim Harris       this_controller,
1564f11c7f63SJim Harris       this_controller->phy_startup_timer
1565f11c7f63SJim Harris    );
1566f11c7f63SJim Harris 
1567f11c7f63SJim Harris    this_controller->phy_startup_timer_pending = FALSE;
1568f11c7f63SJim Harris }
1569f11c7f63SJim Harris 
1570f11c7f63SJim Harris /**
1571f11c7f63SJim Harris  * @brief This method is called internally to determine whether the
1572f11c7f63SJim Harris  *        controller start process is complete.  This is only true when:
1573f11c7f63SJim Harris  *          - all links have been given an opportunity to start
1574f11c7f63SJim Harris  *          - have no indication of a connected device
1575f11c7f63SJim Harris  *          - have an indication of a connected device and it has
1576f11c7f63SJim Harris  *             finished the link training process.
1577f11c7f63SJim Harris  *
1578f11c7f63SJim Harris  * @param[in] this_controller This parameter specifies the controller
1579f11c7f63SJim Harris  *            object for which to start the next phy.
1580f11c7f63SJim Harris  *
1581f11c7f63SJim Harris  * @return BOOL
1582f11c7f63SJim Harris  */
scic_sds_controller_is_start_complete(SCIC_SDS_CONTROLLER_T * this_controller)1583f11c7f63SJim Harris BOOL scic_sds_controller_is_start_complete(
1584f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
1585f11c7f63SJim Harris )
1586f11c7f63SJim Harris {
1587f11c7f63SJim Harris    U8 index;
1588f11c7f63SJim Harris 
1589f11c7f63SJim Harris    for (index = 0; index < SCI_MAX_PHYS; index++)
1590f11c7f63SJim Harris    {
1591f11c7f63SJim Harris       SCIC_SDS_PHY_T *the_phy = & this_controller->phy_table[index];
1592f11c7f63SJim Harris 
1593f11c7f63SJim Harris       if (
1594f11c7f63SJim Harris             (
1595f11c7f63SJim Harris                   this_controller->oem_parameters.sds1.controller.mode_type
1596f11c7f63SJim Harris                == SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE
1597f11c7f63SJim Harris             )
1598f11c7f63SJim Harris          || (
1599f11c7f63SJim Harris                (
1600f11c7f63SJim Harris                   this_controller->oem_parameters.sds1.controller.mode_type
1601f11c7f63SJim Harris                == SCIC_PORT_MANUAL_CONFIGURATION_MODE
1602f11c7f63SJim Harris                )
1603f11c7f63SJim Harris             && (scic_sds_phy_get_port(the_phy) != SCI_INVALID_HANDLE)
1604f11c7f63SJim Harris             )
1605f11c7f63SJim Harris          )
1606f11c7f63SJim Harris       {
1607f11c7f63SJim Harris          /**
1608f11c7f63SJim Harris           * The controller start operation is complete if and only
1609f11c7f63SJim Harris           * if:
1610f11c7f63SJim Harris           * - all links have been given an opportunity to start
1611f11c7f63SJim Harris           * - have no indication of a connected device
1612f11c7f63SJim Harris           * - have an indication of a connected device and it has
1613f11c7f63SJim Harris           *   finished the link training process.
1614f11c7f63SJim Harris           */
1615f11c7f63SJim Harris         if (
1616f11c7f63SJim Harris                (
1617f11c7f63SJim Harris                   (the_phy->is_in_link_training == FALSE)
1618f11c7f63SJim Harris                && (the_phy->parent.state_machine.current_state_id
1619f11c7f63SJim Harris                    == SCI_BASE_PHY_STATE_INITIAL)
1620f11c7f63SJim Harris                )
1621f11c7f63SJim Harris             || (
1622f11c7f63SJim Harris                   (the_phy->is_in_link_training == FALSE)
1623f11c7f63SJim Harris                && (the_phy->parent.state_machine.current_state_id
1624f11c7f63SJim Harris                    == SCI_BASE_PHY_STATE_STOPPED)
1625f11c7f63SJim Harris                )
1626f11c7f63SJim Harris             || (
1627f11c7f63SJim Harris                   (the_phy->is_in_link_training == TRUE)
1628f11c7f63SJim Harris                && (the_phy->parent.state_machine.current_state_id
1629f11c7f63SJim Harris                    == SCI_BASE_PHY_STATE_STARTING)
1630f11c7f63SJim Harris                )
1631f11c7f63SJim Harris             || (
1632f11c7f63SJim Harris                   this_controller->port_agent.phy_ready_mask
1633f11c7f63SJim Harris                   != this_controller->port_agent.phy_configured_mask
1634f11c7f63SJim Harris                )
1635f11c7f63SJim Harris             )
1636f11c7f63SJim Harris          {
1637f11c7f63SJim Harris             return FALSE;
1638f11c7f63SJim Harris          }
1639f11c7f63SJim Harris       }
1640f11c7f63SJim Harris    }
1641f11c7f63SJim Harris 
1642f11c7f63SJim Harris    return TRUE;
1643f11c7f63SJim Harris }
1644f11c7f63SJim Harris 
1645f11c7f63SJim Harris /**
1646f11c7f63SJim Harris  * @brief This method is called internally by the controller object to
1647f11c7f63SJim Harris  *        start the next phy on the controller.  If all the phys have
1648f11c7f63SJim Harris  *        been starte, then this method will attempt to transition the
1649f11c7f63SJim Harris  *        controller to the READY state and inform the user
1650f11c7f63SJim Harris  *        (scic_cb_controller_start_complete()).
1651f11c7f63SJim Harris  *
1652f11c7f63SJim Harris  * @param[in] this_controller This parameter specifies the controller
1653f11c7f63SJim Harris  *            object for which to start the next phy.
1654f11c7f63SJim Harris  *
1655f11c7f63SJim Harris  * @return SCI_STATUS
1656f11c7f63SJim Harris  */
scic_sds_controller_start_next_phy(SCIC_SDS_CONTROLLER_T * this_controller)1657f11c7f63SJim Harris SCI_STATUS scic_sds_controller_start_next_phy(
1658f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
1659f11c7f63SJim Harris )
1660f11c7f63SJim Harris {
1661f11c7f63SJim Harris    SCI_STATUS status;
1662f11c7f63SJim Harris 
1663f11c7f63SJim Harris    status = SCI_SUCCESS;
1664f11c7f63SJim Harris 
1665f11c7f63SJim Harris    if (this_controller->phy_startup_timer_pending == FALSE)
1666f11c7f63SJim Harris    {
1667f11c7f63SJim Harris       if (this_controller->next_phy_to_start == SCI_MAX_PHYS)
1668f11c7f63SJim Harris       {
1669f11c7f63SJim Harris          // The controller has successfully finished the start process.
1670f11c7f63SJim Harris          // Inform the SCI Core user and transition to the READY state.
1671f11c7f63SJim Harris          if (scic_sds_controller_is_start_complete(this_controller) == TRUE)
1672f11c7f63SJim Harris          {
1673f11c7f63SJim Harris             scic_sds_controller_transition_to_ready(
1674f11c7f63SJim Harris                this_controller, SCI_SUCCESS
1675f11c7f63SJim Harris             );
1676f11c7f63SJim Harris          }
1677f11c7f63SJim Harris       }
1678f11c7f63SJim Harris       else
1679f11c7f63SJim Harris       {
1680f11c7f63SJim Harris          SCIC_SDS_PHY_T * the_phy;
1681f11c7f63SJim Harris 
1682f11c7f63SJim Harris          the_phy = &this_controller->phy_table[this_controller->next_phy_to_start];
1683f11c7f63SJim Harris 
1684f11c7f63SJim Harris          if (
1685f11c7f63SJim Harris                this_controller->oem_parameters.sds1.controller.mode_type
1686f11c7f63SJim Harris             == SCIC_PORT_MANUAL_CONFIGURATION_MODE
1687f11c7f63SJim Harris             )
1688f11c7f63SJim Harris          {
1689f11c7f63SJim Harris             if (scic_sds_phy_get_port(the_phy) == SCI_INVALID_HANDLE)
1690f11c7f63SJim Harris             {
1691f11c7f63SJim Harris                this_controller->next_phy_to_start++;
1692f11c7f63SJim Harris 
1693f11c7f63SJim Harris                // Caution recursion ahead be forwarned
1694f11c7f63SJim Harris                //
1695f11c7f63SJim Harris                // The PHY was never added to a PORT in MPC mode so start the next phy in sequence
1696f11c7f63SJim Harris                // This phy will never go link up and will not draw power the OEM parameters either
1697f11c7f63SJim Harris                // configured the phy incorrectly for the PORT or it was never assigned to a PORT
1698f11c7f63SJim Harris                return scic_sds_controller_start_next_phy(this_controller);
1699f11c7f63SJim Harris             }
1700f11c7f63SJim Harris          }
1701f11c7f63SJim Harris 
1702f11c7f63SJim Harris          status = scic_phy_start(the_phy);
1703f11c7f63SJim Harris 
1704f11c7f63SJim Harris          if (status == SCI_SUCCESS)
1705f11c7f63SJim Harris          {
1706f11c7f63SJim Harris             scic_sds_controller_phy_timer_start(this_controller);
1707f11c7f63SJim Harris          }
1708f11c7f63SJim Harris          else
1709f11c7f63SJim Harris          {
1710f11c7f63SJim Harris             SCIC_LOG_WARNING((
1711f11c7f63SJim Harris                sci_base_object_get_logger(this_controller),
1712f11c7f63SJim Harris                SCIC_LOG_OBJECT_CONTROLLER | SCIC_LOG_OBJECT_PHY,
1713f11c7f63SJim Harris                "Controller stop operation failed to stop phy %d because of status %d.\n",
1714f11c7f63SJim Harris                this_controller->phy_table[this_controller->next_phy_to_start].phy_index,
1715f11c7f63SJim Harris                status
1716f11c7f63SJim Harris             ));
1717f11c7f63SJim Harris          }
1718f11c7f63SJim Harris 
1719f11c7f63SJim Harris          this_controller->next_phy_to_start++;
1720f11c7f63SJim Harris       }
1721f11c7f63SJim Harris    }
1722f11c7f63SJim Harris 
1723f11c7f63SJim Harris    return status;
1724f11c7f63SJim Harris }
1725f11c7f63SJim Harris 
1726f11c7f63SJim Harris /**
1727f11c7f63SJim Harris  * @brief
1728f11c7f63SJim Harris  *
1729f11c7f63SJim Harris  * @param[in] this_controller
1730f11c7f63SJim Harris  *
1731f11c7f63SJim Harris  * @return SCI_STATUS
1732f11c7f63SJim Harris  */
scic_sds_controller_stop_phys(SCIC_SDS_CONTROLLER_T * this_controller)1733f11c7f63SJim Harris SCI_STATUS scic_sds_controller_stop_phys(
1734f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
1735f11c7f63SJim Harris )
1736f11c7f63SJim Harris {
1737f11c7f63SJim Harris    U32        index;
1738f11c7f63SJim Harris    SCI_STATUS status;
1739f11c7f63SJim Harris    SCI_STATUS phy_status;
1740f11c7f63SJim Harris 
1741f11c7f63SJim Harris    status = SCI_SUCCESS;
1742f11c7f63SJim Harris 
1743f11c7f63SJim Harris    for (index = 0; index < SCI_MAX_PHYS; index++)
1744f11c7f63SJim Harris    {
1745f11c7f63SJim Harris       phy_status = scic_phy_stop(&this_controller->phy_table[index]);
1746f11c7f63SJim Harris 
1747f11c7f63SJim Harris       if (
1748f11c7f63SJim Harris               (phy_status != SCI_SUCCESS)
1749f11c7f63SJim Harris            && (phy_status != SCI_FAILURE_INVALID_STATE)
1750f11c7f63SJim Harris          )
1751f11c7f63SJim Harris       {
1752f11c7f63SJim Harris          status = SCI_FAILURE;
1753f11c7f63SJim Harris 
1754f11c7f63SJim Harris          SCIC_LOG_WARNING((
1755f11c7f63SJim Harris             sci_base_object_get_logger(this_controller),
1756f11c7f63SJim Harris             SCIC_LOG_OBJECT_CONTROLLER | SCIC_LOG_OBJECT_PHY,
1757f11c7f63SJim Harris             "Controller stop operation failed to stop phy %d because of status %d.\n",
1758f11c7f63SJim Harris             this_controller->phy_table[index].phy_index, phy_status
1759f11c7f63SJim Harris          ));
1760f11c7f63SJim Harris       }
1761f11c7f63SJim Harris    }
1762f11c7f63SJim Harris 
1763f11c7f63SJim Harris    return status;
1764f11c7f63SJim Harris }
1765f11c7f63SJim Harris 
1766f11c7f63SJim Harris /**
1767f11c7f63SJim Harris  * @brief
1768f11c7f63SJim Harris  *
1769f11c7f63SJim Harris  * @param[in] this_controller
1770f11c7f63SJim Harris  *
1771f11c7f63SJim Harris  * @return SCI_STATUS
1772f11c7f63SJim Harris  */
scic_sds_controller_stop_devices(SCIC_SDS_CONTROLLER_T * this_controller)1773f11c7f63SJim Harris SCI_STATUS scic_sds_controller_stop_devices(
1774f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
1775f11c7f63SJim Harris )
1776f11c7f63SJim Harris {
1777f11c7f63SJim Harris    U32        index;
1778f11c7f63SJim Harris    SCI_STATUS status;
1779f11c7f63SJim Harris    SCI_STATUS device_status;
1780f11c7f63SJim Harris 
1781f11c7f63SJim Harris    status = SCI_SUCCESS;
1782f11c7f63SJim Harris 
1783f11c7f63SJim Harris    for (index = 0; index < this_controller->remote_node_entries; index++)
1784f11c7f63SJim Harris    {
1785f11c7f63SJim Harris       if (this_controller->device_table[index] != SCI_INVALID_HANDLE)
1786f11c7f63SJim Harris       {
1787f11c7f63SJim Harris          /// @todo What timeout value do we want to provide to this request?
1788f11c7f63SJim Harris          device_status = scic_remote_device_stop(this_controller->device_table[index], 0);
1789f11c7f63SJim Harris 
1790f11c7f63SJim Harris          if (
1791f11c7f63SJim Harris                  (device_status != SCI_SUCCESS)
1792f11c7f63SJim Harris               && (device_status != SCI_FAILURE_INVALID_STATE)
1793f11c7f63SJim Harris             )
1794f11c7f63SJim Harris          {
1795f11c7f63SJim Harris             SCIC_LOG_WARNING((
1796f11c7f63SJim Harris                sci_base_object_get_logger(this_controller),
1797f11c7f63SJim Harris                SCIC_LOG_OBJECT_CONTROLLER | SCIC_LOG_OBJECT_SSP_REMOTE_TARGET,
1798f11c7f63SJim Harris                "Controller stop operation failed to stop device 0x%x because of status %d.\n",
1799f11c7f63SJim Harris                this_controller->device_table[index], device_status
1800f11c7f63SJim Harris             ));
1801f11c7f63SJim Harris          }
1802f11c7f63SJim Harris       }
1803f11c7f63SJim Harris    }
1804f11c7f63SJim Harris 
1805f11c7f63SJim Harris    return status;
1806f11c7f63SJim Harris }
1807f11c7f63SJim Harris 
1808f11c7f63SJim Harris //****************************************************************************-
1809f11c7f63SJim Harris //* SCIC SDS Controller Power Control (Staggered Spinup)
1810f11c7f63SJim Harris //****************************************************************************-
1811f11c7f63SJim Harris 
1812f11c7f63SJim Harris /**
1813f11c7f63SJim Harris  * This method starts the power control timer for this controller object.
1814f11c7f63SJim Harris  *
1815f11c7f63SJim Harris  * @param this_controller
1816f11c7f63SJim Harris  */
1817f11c7f63SJim Harris static
scic_sds_controller_power_control_timer_start(SCIC_SDS_CONTROLLER_T * this_controller)1818f11c7f63SJim Harris void scic_sds_controller_power_control_timer_start(
1819f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
1820f11c7f63SJim Harris )
1821f11c7f63SJim Harris {
1822f11c7f63SJim Harris    scic_cb_timer_start(
1823f11c7f63SJim Harris       this_controller, this_controller->power_control.timer,
1824f11c7f63SJim Harris       SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL
1825f11c7f63SJim Harris    );
1826f11c7f63SJim Harris 
1827f11c7f63SJim Harris    this_controller->power_control.timer_started = TRUE;
1828f11c7f63SJim Harris }
1829f11c7f63SJim Harris 
1830f11c7f63SJim Harris /**
1831f11c7f63SJim Harris  * This method stops the power control timer for this controller object.
1832f11c7f63SJim Harris  *
1833f11c7f63SJim Harris  * @param this_controller
1834f11c7f63SJim Harris  */
1835f11c7f63SJim Harris static
scic_sds_controller_power_control_timer_stop(SCIC_SDS_CONTROLLER_T * this_controller)1836f11c7f63SJim Harris void scic_sds_controller_power_control_timer_stop(
1837f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
1838f11c7f63SJim Harris )
1839f11c7f63SJim Harris {
1840f11c7f63SJim Harris    if (this_controller->power_control.timer_started)
1841f11c7f63SJim Harris    {
1842f11c7f63SJim Harris       scic_cb_timer_stop(
1843f11c7f63SJim Harris          this_controller, this_controller->power_control.timer
1844f11c7f63SJim Harris       );
1845f11c7f63SJim Harris 
1846f11c7f63SJim Harris       this_controller->power_control.timer_started = FALSE;
1847f11c7f63SJim Harris    }
1848f11c7f63SJim Harris }
1849f11c7f63SJim Harris 
1850f11c7f63SJim Harris /**
1851f11c7f63SJim Harris  * This method stops and starts the power control timer for this controller object.
1852f11c7f63SJim Harris  *
1853f11c7f63SJim Harris  * @param this_controller
1854f11c7f63SJim Harris  */
1855f11c7f63SJim Harris static
scic_sds_controller_power_control_timer_restart(SCIC_SDS_CONTROLLER_T * this_controller)1856f11c7f63SJim Harris void scic_sds_controller_power_control_timer_restart(
1857f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
1858f11c7f63SJim Harris )
1859f11c7f63SJim Harris {
1860f11c7f63SJim Harris    scic_sds_controller_power_control_timer_stop(this_controller);
1861f11c7f63SJim Harris    scic_sds_controller_power_control_timer_start(this_controller);
1862f11c7f63SJim Harris }
1863f11c7f63SJim Harris 
1864f11c7f63SJim Harris 
1865f11c7f63SJim Harris /**
1866f11c7f63SJim Harris  * @brief
1867f11c7f63SJim Harris  *
1868f11c7f63SJim Harris  * @param[in] controller
1869f11c7f63SJim Harris  */
scic_sds_controller_power_control_timer_handler(void * controller)1870f11c7f63SJim Harris void scic_sds_controller_power_control_timer_handler(
1871f11c7f63SJim Harris    void *controller
1872f11c7f63SJim Harris )
1873f11c7f63SJim Harris {
1874f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
1875f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
1876f11c7f63SJim Harris 
1877f11c7f63SJim Harris    this_controller->power_control.remote_devices_granted_power = 0;
1878f11c7f63SJim Harris 
1879f11c7f63SJim Harris    if (this_controller->power_control.phys_waiting == 0)
1880f11c7f63SJim Harris    {
1881f11c7f63SJim Harris       this_controller->power_control.timer_started = FALSE;
1882f11c7f63SJim Harris    }
1883f11c7f63SJim Harris    else
1884f11c7f63SJim Harris    {
1885f11c7f63SJim Harris       SCIC_SDS_PHY_T *the_phy = NULL;
1886f11c7f63SJim Harris       U8 i;
1887f11c7f63SJim Harris 
1888f11c7f63SJim Harris       for (i=0;
1889f11c7f63SJim Harris               (i < SCI_MAX_PHYS)
1890f11c7f63SJim Harris            && (this_controller->power_control.phys_waiting != 0);
1891f11c7f63SJim Harris            i++)
1892f11c7f63SJim Harris       {
1893f11c7f63SJim Harris          if (this_controller->power_control.requesters[i] != NULL)
1894f11c7f63SJim Harris          {
1895f11c7f63SJim Harris             if ( this_controller->power_control.remote_devices_granted_power <
1896f11c7f63SJim Harris                  this_controller->oem_parameters.sds1.controller.max_number_concurrent_device_spin_up
1897f11c7f63SJim Harris                )
1898f11c7f63SJim Harris             {
1899f11c7f63SJim Harris                the_phy = this_controller->power_control.requesters[i];
1900f11c7f63SJim Harris                this_controller->power_control.requesters[i] = NULL;
1901f11c7f63SJim Harris                this_controller->power_control.phys_waiting--;
1902f11c7f63SJim Harris                this_controller->power_control.remote_devices_granted_power ++;
1903f11c7f63SJim Harris                scic_sds_phy_consume_power_handler(the_phy);
1904f11c7f63SJim Harris 
1905f11c7f63SJim Harris                if (the_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS)
1906f11c7f63SJim Harris                {
1907f11c7f63SJim Harris                   U8 j;
1908f11c7f63SJim Harris                   SCIC_SDS_PHY_T * current_requester_phy;
1909f11c7f63SJim Harris 
1910f11c7f63SJim Harris                   for (j = 0; j < SCI_MAX_PHYS; j++)
1911f11c7f63SJim Harris                   {
1912f11c7f63SJim Harris                      current_requester_phy = this_controller->power_control.requesters[j];
1913f11c7f63SJim Harris 
1914f11c7f63SJim Harris                      //Search the power_control queue to see if there are other phys attached to
1915f11c7f63SJim Harris                      //the same remote device. If found, take all of them out of await_sas_power state.
1916f11c7f63SJim Harris                      if (current_requester_phy != NULL &&
1917f11c7f63SJim Harris                          current_requester_phy != the_phy &&
1918f11c7f63SJim Harris                          current_requester_phy->phy_type.sas.identify_address_frame_buffer.sas_address.high
1919f11c7f63SJim Harris                             == the_phy->phy_type.sas.identify_address_frame_buffer.sas_address.high &&
1920f11c7f63SJim Harris                          current_requester_phy->phy_type.sas.identify_address_frame_buffer.sas_address.low
1921f11c7f63SJim Harris                             == the_phy->phy_type.sas.identify_address_frame_buffer.sas_address.low)
1922f11c7f63SJim Harris                      {
1923f11c7f63SJim Harris                         this_controller->power_control.requesters[j] = NULL;
1924f11c7f63SJim Harris                         this_controller->power_control.phys_waiting--;
1925f11c7f63SJim Harris                         scic_sds_phy_consume_power_handler(current_requester_phy);
1926f11c7f63SJim Harris                      }
1927f11c7f63SJim Harris                   }
1928f11c7f63SJim Harris                }
1929f11c7f63SJim Harris             }
1930f11c7f63SJim Harris             else
1931f11c7f63SJim Harris             {
1932f11c7f63SJim Harris                break;
1933f11c7f63SJim Harris             }
1934f11c7f63SJim Harris          }
1935f11c7f63SJim Harris       }
1936f11c7f63SJim Harris 
1937f11c7f63SJim Harris       // It doesn't matter if the power list is empty, we need to start the
1938f11c7f63SJim Harris       // timer in case another phy becomes ready.
1939f11c7f63SJim Harris       scic_sds_controller_power_control_timer_start(this_controller);
1940f11c7f63SJim Harris    }
1941f11c7f63SJim Harris }
1942f11c7f63SJim Harris 
1943f11c7f63SJim Harris /**
1944f11c7f63SJim Harris  * @brief This method inserts the phy in the stagger spinup control queue.
1945f11c7f63SJim Harris  *
1946f11c7f63SJim Harris  * @param[in] this_controller
1947f11c7f63SJim Harris  * @param[in] the_phy
1948f11c7f63SJim Harris  */
scic_sds_controller_power_control_queue_insert(SCIC_SDS_CONTROLLER_T * this_controller,SCIC_SDS_PHY_T * the_phy)1949f11c7f63SJim Harris void scic_sds_controller_power_control_queue_insert(
1950f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller,
1951f11c7f63SJim Harris    SCIC_SDS_PHY_T        *the_phy
1952f11c7f63SJim Harris )
1953f11c7f63SJim Harris {
1954f11c7f63SJim Harris    ASSERT (the_phy != NULL);
1955f11c7f63SJim Harris 
1956f11c7f63SJim Harris    if( this_controller->power_control.remote_devices_granted_power <
1957f11c7f63SJim Harris        this_controller->oem_parameters.sds1.controller.max_number_concurrent_device_spin_up
1958f11c7f63SJim Harris      )
1959f11c7f63SJim Harris    {
1960f11c7f63SJim Harris       this_controller->power_control.remote_devices_granted_power ++;
1961f11c7f63SJim Harris       scic_sds_phy_consume_power_handler(the_phy);
1962f11c7f63SJim Harris 
1963f11c7f63SJim Harris       //stop and start the power_control timer. When the timer fires, the
1964f11c7f63SJim Harris       //no_of_devices_granted_power will be set to 0
1965f11c7f63SJim Harris       scic_sds_controller_power_control_timer_restart (this_controller);
1966f11c7f63SJim Harris    }
1967f11c7f63SJim Harris    else
1968f11c7f63SJim Harris    {
1969f11c7f63SJim Harris       //there are phys, attached to the same sas address as this phy, are already
1970f11c7f63SJim Harris       //in READY state, this phy don't need wait.
1971f11c7f63SJim Harris       U8 i;
1972f11c7f63SJim Harris       SCIC_SDS_PHY_T * current_phy;
1973f11c7f63SJim Harris       for(i = 0; i < SCI_MAX_PHYS; i++)
1974f11c7f63SJim Harris       {
1975f11c7f63SJim Harris          current_phy = &this_controller->phy_table[i];
1976f11c7f63SJim Harris 
1977f11c7f63SJim Harris          if (current_phy->parent.state_machine.current_state_id == SCI_BASE_PHY_STATE_READY &&
1978f11c7f63SJim Harris              current_phy->protocol == SCIC_SDS_PHY_PROTOCOL_SAS &&
1979f11c7f63SJim Harris              current_phy->phy_type.sas.identify_address_frame_buffer.sas_address.high
1980f11c7f63SJim Harris                 == the_phy->phy_type.sas.identify_address_frame_buffer.sas_address.high &&
1981f11c7f63SJim Harris              current_phy->phy_type.sas.identify_address_frame_buffer.sas_address.low
1982f11c7f63SJim Harris                 == the_phy->phy_type.sas.identify_address_frame_buffer.sas_address.low)
1983f11c7f63SJim Harris          {
1984f11c7f63SJim Harris             scic_sds_phy_consume_power_handler(the_phy);
1985f11c7f63SJim Harris             break;
1986f11c7f63SJim Harris          }
1987f11c7f63SJim Harris       }
1988f11c7f63SJim Harris 
1989f11c7f63SJim Harris       if (i == SCI_MAX_PHYS)
1990f11c7f63SJim Harris       {
1991f11c7f63SJim Harris          //Add the phy in the waiting list
1992f11c7f63SJim Harris          this_controller->power_control.requesters[the_phy->phy_index] = the_phy;
1993f11c7f63SJim Harris          this_controller->power_control.phys_waiting++;
1994f11c7f63SJim Harris       }
1995f11c7f63SJim Harris    }
1996f11c7f63SJim Harris }
1997f11c7f63SJim Harris 
1998f11c7f63SJim Harris /**
1999f11c7f63SJim Harris  * @brief This method removes the phy from the stagger spinup control
2000f11c7f63SJim Harris  *        queue.
2001f11c7f63SJim Harris  *
2002f11c7f63SJim Harris  * @param[in] this_controller
2003f11c7f63SJim Harris  * @param[in] the_phy
2004f11c7f63SJim Harris  */
scic_sds_controller_power_control_queue_remove(SCIC_SDS_CONTROLLER_T * this_controller,SCIC_SDS_PHY_T * the_phy)2005f11c7f63SJim Harris void scic_sds_controller_power_control_queue_remove(
2006f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller,
2007f11c7f63SJim Harris    SCIC_SDS_PHY_T        *the_phy
2008f11c7f63SJim Harris )
2009f11c7f63SJim Harris {
2010f11c7f63SJim Harris    ASSERT (the_phy != NULL);
2011f11c7f63SJim Harris 
2012f11c7f63SJim Harris    if (this_controller->power_control.requesters[the_phy->phy_index] != NULL)
2013f11c7f63SJim Harris    {
2014f11c7f63SJim Harris       this_controller->power_control.phys_waiting--;
2015f11c7f63SJim Harris    }
2016f11c7f63SJim Harris 
2017f11c7f63SJim Harris    this_controller->power_control.requesters[the_phy->phy_index] = NULL;
2018f11c7f63SJim Harris }
2019f11c7f63SJim Harris 
2020f11c7f63SJim Harris //****************************************************************************-
2021f11c7f63SJim Harris //* SCIC SDS Controller Completion Routines
2022f11c7f63SJim Harris //****************************************************************************-
2023f11c7f63SJim Harris 
2024f11c7f63SJim Harris /**
2025f11c7f63SJim Harris  * @brief This method returns a TRUE value if the completion queue has
2026f11c7f63SJim Harris  *        entries that can be processed
2027f11c7f63SJim Harris  *
2028f11c7f63SJim Harris  * @param[in] this_controller
2029f11c7f63SJim Harris  *
2030f11c7f63SJim Harris  * @return BOOL
2031f11c7f63SJim Harris  * @retval TRUE if the completion queue has entries to process
2032f11c7f63SJim Harris  *         FALSE if the completion queue has no entries to process
2033f11c7f63SJim Harris  */
2034f11c7f63SJim Harris static
scic_sds_controller_completion_queue_has_entries(SCIC_SDS_CONTROLLER_T * this_controller)2035f11c7f63SJim Harris BOOL scic_sds_controller_completion_queue_has_entries(
2036f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
2037f11c7f63SJim Harris )
2038f11c7f63SJim Harris {
2039f11c7f63SJim Harris    U32 get_value = this_controller->completion_queue_get;
2040f11c7f63SJim Harris    U32 get_index = get_value & SMU_COMPLETION_QUEUE_GET_POINTER_MASK;
2041f11c7f63SJim Harris    if (
2042f11c7f63SJim Harris            NORMALIZE_GET_POINTER_CYCLE_BIT(get_value)
2043f11c7f63SJim Harris         == COMPLETION_QUEUE_CYCLE_BIT(this_controller->completion_queue[get_index])
2044f11c7f63SJim Harris       )
2045f11c7f63SJim Harris    {
2046f11c7f63SJim Harris       return TRUE;
2047f11c7f63SJim Harris    }
2048f11c7f63SJim Harris 
2049f11c7f63SJim Harris    return FALSE;
2050f11c7f63SJim Harris }
2051f11c7f63SJim Harris 
2052f11c7f63SJim Harris // ---------------------------------------------------------------------------
2053f11c7f63SJim Harris 
2054f11c7f63SJim Harris /**
2055f11c7f63SJim Harris  * @brief This method processes a task completion notification.  This is
2056f11c7f63SJim Harris  *        called from within the controller completion handler.
2057f11c7f63SJim Harris  *
2058f11c7f63SJim Harris  * @param[in] this_controller
2059f11c7f63SJim Harris  * @param[in] completion_entry
2060f11c7f63SJim Harris  *
2061f11c7f63SJim Harris  * @return none
2062f11c7f63SJim Harris  */
2063f11c7f63SJim Harris static
scic_sds_controller_task_completion(SCIC_SDS_CONTROLLER_T * this_controller,U32 completion_entry)2064f11c7f63SJim Harris void scic_sds_controller_task_completion(
2065f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller,
2066f11c7f63SJim Harris    U32                   completion_entry
2067f11c7f63SJim Harris )
2068f11c7f63SJim Harris {
2069f11c7f63SJim Harris    U32 index;
2070f11c7f63SJim Harris    SCIC_SDS_REQUEST_T *io_request;
2071f11c7f63SJim Harris 
2072f11c7f63SJim Harris    index = SCU_GET_COMPLETION_INDEX(completion_entry);
2073f11c7f63SJim Harris    io_request = this_controller->io_request_table[index];
2074f11c7f63SJim Harris 
2075f11c7f63SJim Harris    // Make sure that we really want to process this IO request
2076f11c7f63SJim Harris    if (
2077f11c7f63SJim Harris            (io_request != SCI_INVALID_HANDLE)
2078f11c7f63SJim Harris         && (io_request->io_tag != SCI_CONTROLLER_INVALID_IO_TAG)
2079f11c7f63SJim Harris         && (
2080f11c7f63SJim Harris                 scic_sds_io_tag_get_sequence(io_request->io_tag)
2081f11c7f63SJim Harris              == this_controller->io_request_sequence[index]
2082f11c7f63SJim Harris            )
2083f11c7f63SJim Harris       )
2084f11c7f63SJim Harris    {
2085f11c7f63SJim Harris       // Yep this is a valid io request pass it along to the io request handler
2086f11c7f63SJim Harris       scic_sds_io_request_tc_completion(io_request, completion_entry);
2087f11c7f63SJim Harris    }
2088f11c7f63SJim Harris }
2089f11c7f63SJim Harris 
2090f11c7f63SJim Harris /**
2091f11c7f63SJim Harris  * @brief This method processes an SDMA completion event.  This is called
2092f11c7f63SJim Harris  *        from within the controller completion handler.
2093f11c7f63SJim Harris  *
2094f11c7f63SJim Harris  * @param[in] this_controller
2095f11c7f63SJim Harris  * @param[in] completion_entry
2096f11c7f63SJim Harris  *
2097f11c7f63SJim Harris  * @return none
2098f11c7f63SJim Harris  */
2099f11c7f63SJim Harris static
scic_sds_controller_sdma_completion(SCIC_SDS_CONTROLLER_T * this_controller,U32 completion_entry)2100f11c7f63SJim Harris void scic_sds_controller_sdma_completion(
2101f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller,
2102f11c7f63SJim Harris    U32                   completion_entry
2103f11c7f63SJim Harris )
2104f11c7f63SJim Harris {
2105f11c7f63SJim Harris    U32 index;
2106f11c7f63SJim Harris    SCIC_SDS_REQUEST_T       *io_request;
2107f11c7f63SJim Harris    SCIC_SDS_REMOTE_DEVICE_T *device;
2108f11c7f63SJim Harris 
2109f11c7f63SJim Harris    index = SCU_GET_COMPLETION_INDEX(completion_entry);
2110f11c7f63SJim Harris 
2111f11c7f63SJim Harris    switch (scu_get_command_request_type(completion_entry))
2112f11c7f63SJim Harris    {
2113f11c7f63SJim Harris    case SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC:
2114f11c7f63SJim Harris    case SCU_CONTEXT_COMMAND_REQUEST_TYPE_DUMP_TC:
2115f11c7f63SJim Harris       io_request = this_controller->io_request_table[index];
2116f11c7f63SJim Harris       SCIC_LOG_ERROR((
2117f11c7f63SJim Harris          sci_base_object_get_logger(this_controller),
2118f11c7f63SJim Harris            SCIC_LOG_OBJECT_CONTROLLER
2119f11c7f63SJim Harris          | SCIC_LOG_OBJECT_SMP_IO_REQUEST
2120f11c7f63SJim Harris          | SCIC_LOG_OBJECT_SSP_IO_REQUEST
2121f11c7f63SJim Harris          | SCIC_LOG_OBJECT_STP_IO_REQUEST,
2122f11c7f63SJim Harris          "SCIC SDS Completion type SDMA %x for io request %x\n",
2123f11c7f63SJim Harris          completion_entry,
2124f11c7f63SJim Harris          io_request
2125f11c7f63SJim Harris       ));
2126f11c7f63SJim Harris       /// @todo For a post TC operation we need to fail the IO request
2127f11c7f63SJim Harris       break;
2128f11c7f63SJim Harris 
2129f11c7f63SJim Harris    case SCU_CONTEXT_COMMAND_REQUEST_TYPE_DUMP_RNC:
2130f11c7f63SJim Harris    case SCU_CONTEXT_COMMAND_REQUEST_TYPE_OTHER_RNC:
2131f11c7f63SJim Harris    case SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_RNC:
2132f11c7f63SJim Harris       device = this_controller->device_table[index];
2133f11c7f63SJim Harris       SCIC_LOG_ERROR((
2134f11c7f63SJim Harris          sci_base_object_get_logger(this_controller),
2135f11c7f63SJim Harris            SCIC_LOG_OBJECT_CONTROLLER
2136f11c7f63SJim Harris          | SCIC_LOG_OBJECT_SSP_REMOTE_TARGET
2137f11c7f63SJim Harris          | SCIC_LOG_OBJECT_SMP_REMOTE_TARGET
2138f11c7f63SJim Harris          | SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
2139f11c7f63SJim Harris          "SCIC SDS Completion type SDMA %x for remote device %x\n",
2140f11c7f63SJim Harris          completion_entry,
2141f11c7f63SJim Harris          device
2142f11c7f63SJim Harris       ));
2143f11c7f63SJim Harris       /// @todo For a port RNC operation we need to fail the device
2144f11c7f63SJim Harris       break;
2145f11c7f63SJim Harris 
2146f11c7f63SJim Harris    default:
2147f11c7f63SJim Harris       SCIC_LOG_ERROR((
2148f11c7f63SJim Harris          sci_base_object_get_logger(this_controller),
2149f11c7f63SJim Harris          SCIC_LOG_OBJECT_CONTROLLER,
2150f11c7f63SJim Harris          "SCIC SDS Completion unknown SDMA completion type %x\n",
2151f11c7f63SJim Harris          completion_entry
2152f11c7f63SJim Harris       ));
2153f11c7f63SJim Harris       break;
2154f11c7f63SJim Harris    }
2155f11c7f63SJim Harris 
2156f11c7f63SJim Harris    /// This is an unexpected completion type and is un-recoverable
2157f11c7f63SJim Harris    /// Transition to the failed state and wait for a controller reset
2158f11c7f63SJim Harris    sci_base_state_machine_change_state(
2159f11c7f63SJim Harris       scic_sds_controller_get_base_state_machine(this_controller),
2160f11c7f63SJim Harris       SCI_BASE_CONTROLLER_STATE_FAILED
2161f11c7f63SJim Harris    );
2162f11c7f63SJim Harris }
2163f11c7f63SJim Harris 
2164f11c7f63SJim Harris /**
2165f11c7f63SJim Harris  * This method processes an unsolicited frame message.  This is called from
2166f11c7f63SJim Harris  * within the controller completion handler.
2167f11c7f63SJim Harris  *
2168f11c7f63SJim Harris  * @param[in] this_controller
2169f11c7f63SJim Harris  * @param[in] completion_entry
2170f11c7f63SJim Harris  *
2171f11c7f63SJim Harris  * @return none
2172f11c7f63SJim Harris  */
2173f11c7f63SJim Harris static
scic_sds_controller_unsolicited_frame(SCIC_SDS_CONTROLLER_T * this_controller,U32 completion_entry)2174f11c7f63SJim Harris void scic_sds_controller_unsolicited_frame(
2175f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller,
2176f11c7f63SJim Harris    U32                   completion_entry
2177f11c7f63SJim Harris )
2178f11c7f63SJim Harris {
2179f11c7f63SJim Harris    U32 index;
2180f11c7f63SJim Harris    U32 frame_index;
2181f11c7f63SJim Harris 
2182f11c7f63SJim Harris    SCU_UNSOLICITED_FRAME_HEADER_T * frame_header;
2183f11c7f63SJim Harris    SCIC_SDS_PHY_T                 * phy;
2184f11c7f63SJim Harris    SCIC_SDS_REMOTE_DEVICE_T       * device;
2185f11c7f63SJim Harris 
2186f11c7f63SJim Harris    SCI_STATUS result = SCI_FAILURE;
2187f11c7f63SJim Harris 
2188f11c7f63SJim Harris    frame_index = SCU_GET_FRAME_INDEX(completion_entry);
2189f11c7f63SJim Harris 
2190f11c7f63SJim Harris    frame_header
2191f11c7f63SJim Harris       = this_controller->uf_control.buffers.array[frame_index].header;
2192f11c7f63SJim Harris    this_controller->uf_control.buffers.array[frame_index].state
2193f11c7f63SJim Harris       = UNSOLICITED_FRAME_IN_USE;
2194f11c7f63SJim Harris 
2195f11c7f63SJim Harris    if (SCU_GET_FRAME_ERROR(completion_entry))
2196f11c7f63SJim Harris    {
2197f11c7f63SJim Harris       /// @todo If the IAF frame or SIGNATURE FIS frame has an error will
2198f11c7f63SJim Harris       ///       this cause a problem? We expect the phy initialization will
2199f11c7f63SJim Harris       ///       fail if there is an error in the frame.
2200f11c7f63SJim Harris       scic_sds_controller_release_frame(this_controller, frame_index);
2201f11c7f63SJim Harris       return;
2202f11c7f63SJim Harris    }
2203f11c7f63SJim Harris 
2204f11c7f63SJim Harris    if (frame_header->is_address_frame)
2205f11c7f63SJim Harris    {
2206f11c7f63SJim Harris       index = SCU_GET_PROTOCOL_ENGINE_INDEX(completion_entry);
2207f11c7f63SJim Harris       phy = &this_controller->phy_table[index];
2208f11c7f63SJim Harris       if (phy != NULL)
2209f11c7f63SJim Harris       {
2210f11c7f63SJim Harris          result = scic_sds_phy_frame_handler(phy, frame_index);
2211f11c7f63SJim Harris       }
2212f11c7f63SJim Harris    }
2213f11c7f63SJim Harris    else
2214f11c7f63SJim Harris    {
2215f11c7f63SJim Harris 
2216f11c7f63SJim Harris       index = SCU_GET_COMPLETION_INDEX(completion_entry);
2217f11c7f63SJim Harris 
2218f11c7f63SJim Harris       if (index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX)
2219f11c7f63SJim Harris       {
2220f11c7f63SJim Harris          // This is a signature fis or a frame from a direct attached SATA
2221f11c7f63SJim Harris          // device that has not yet been created.  In either case forwared
2222f11c7f63SJim Harris          // the frame to the PE and let it take care of the frame data.
2223f11c7f63SJim Harris          index = SCU_GET_PROTOCOL_ENGINE_INDEX(completion_entry);
2224f11c7f63SJim Harris          phy = &this_controller->phy_table[index];
2225f11c7f63SJim Harris          result = scic_sds_phy_frame_handler(phy, frame_index);
2226f11c7f63SJim Harris       }
2227f11c7f63SJim Harris       else
2228f11c7f63SJim Harris       {
2229f11c7f63SJim Harris          if (index < this_controller->remote_node_entries)
2230f11c7f63SJim Harris             device = this_controller->device_table[index];
2231f11c7f63SJim Harris          else
2232f11c7f63SJim Harris             device = NULL;
2233f11c7f63SJim Harris 
2234f11c7f63SJim Harris          if (device != NULL)
2235f11c7f63SJim Harris             result = scic_sds_remote_device_frame_handler(device, frame_index);
2236f11c7f63SJim Harris          else
2237f11c7f63SJim Harris             scic_sds_controller_release_frame(this_controller, frame_index);
2238f11c7f63SJim Harris       }
2239f11c7f63SJim Harris    }
2240f11c7f63SJim Harris 
2241f11c7f63SJim Harris    if (result != SCI_SUCCESS)
2242f11c7f63SJim Harris    {
2243f11c7f63SJim Harris       /// @todo Is there any reason to report some additional error message
2244f11c7f63SJim Harris       ///       when we get this failure notifiction?
2245f11c7f63SJim Harris    }
2246f11c7f63SJim Harris }
2247f11c7f63SJim Harris 
2248f11c7f63SJim Harris /**
2249f11c7f63SJim Harris  * @brief This method processes an event completion entry.  This is called
2250f11c7f63SJim Harris  *        from within the controller completion handler.
2251f11c7f63SJim Harris  *
2252f11c7f63SJim Harris  * @param[in] this_controller
2253f11c7f63SJim Harris  * @param[in] completion_entry
2254f11c7f63SJim Harris  *
2255f11c7f63SJim Harris  * @return none
2256f11c7f63SJim Harris  */
2257f11c7f63SJim Harris static
scic_sds_controller_event_completion(SCIC_SDS_CONTROLLER_T * this_controller,U32 completion_entry)2258f11c7f63SJim Harris void scic_sds_controller_event_completion(
2259f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller,
2260f11c7f63SJim Harris    U32                   completion_entry
2261f11c7f63SJim Harris )
2262f11c7f63SJim Harris {
2263f11c7f63SJim Harris    U32 index;
2264f11c7f63SJim Harris    SCIC_SDS_REQUEST_T       *io_request;
2265f11c7f63SJim Harris    SCIC_SDS_REMOTE_DEVICE_T *device;
2266f11c7f63SJim Harris    SCIC_SDS_PHY_T           *phy;
2267f11c7f63SJim Harris 
2268f11c7f63SJim Harris    index = SCU_GET_COMPLETION_INDEX(completion_entry);
2269f11c7f63SJim Harris 
2270f11c7f63SJim Harris    switch (scu_get_event_type(completion_entry))
2271f11c7f63SJim Harris    {
2272f11c7f63SJim Harris    case SCU_EVENT_TYPE_SMU_COMMAND_ERROR:
2273f11c7f63SJim Harris       /// @todo The driver did something wrong and we need to fix the condtion.
2274f11c7f63SJim Harris       SCIC_LOG_ERROR((
2275f11c7f63SJim Harris          sci_base_object_get_logger(this_controller),
2276f11c7f63SJim Harris          SCIC_LOG_OBJECT_CONTROLLER,
2277f11c7f63SJim Harris          "SCIC Controller 0x%x received SMU command error 0x%x\n",
2278f11c7f63SJim Harris          this_controller, completion_entry
2279f11c7f63SJim Harris       ));
2280f11c7f63SJim Harris       break;
2281f11c7f63SJim Harris 
2282f11c7f63SJim Harris    case SCU_EVENT_TYPE_FATAL_MEMORY_ERROR:
2283f11c7f63SJim Harris        // report fatal memory error
2284f11c7f63SJim Harris        this_controller->parent.error = SCI_CONTROLLER_FATAL_MEMORY_ERROR;
2285f11c7f63SJim Harris 
2286f11c7f63SJim Harris        sci_base_state_machine_change_state(
2287f11c7f63SJim Harris           scic_sds_controller_get_base_state_machine(this_controller),
2288f11c7f63SJim Harris           SCI_BASE_CONTROLLER_STATE_FAILED
2289f11c7f63SJim Harris        );
2290f11c7f63SJim Harris 
2291f11c7f63SJim Harris        //continue as in following events
2292f11c7f63SJim Harris    case SCU_EVENT_TYPE_SMU_PCQ_ERROR:
2293f11c7f63SJim Harris    case SCU_EVENT_TYPE_SMU_ERROR:
2294f11c7f63SJim Harris       SCIC_LOG_ERROR((
2295f11c7f63SJim Harris          sci_base_object_get_logger(this_controller),
2296f11c7f63SJim Harris          SCIC_LOG_OBJECT_CONTROLLER,
2297f11c7f63SJim Harris          "SCIC Controller 0x%x received fatal controller event 0x%x\n",
2298f11c7f63SJim Harris          this_controller, completion_entry
2299f11c7f63SJim Harris       ));
2300f11c7f63SJim Harris       break;
2301f11c7f63SJim Harris 
2302f11c7f63SJim Harris    case SCU_EVENT_TYPE_TRANSPORT_ERROR:
2303f11c7f63SJim Harris       io_request = this_controller->io_request_table[index];
2304f11c7f63SJim Harris       scic_sds_io_request_event_handler(io_request, completion_entry);
2305f11c7f63SJim Harris       break;
2306f11c7f63SJim Harris 
2307f11c7f63SJim Harris    case SCU_EVENT_TYPE_PTX_SCHEDULE_EVENT:
2308f11c7f63SJim Harris       switch (scu_get_event_specifier(completion_entry))
2309f11c7f63SJim Harris       {
2310f11c7f63SJim Harris       case SCU_EVENT_SPECIFIC_SMP_RESPONSE_NO_PE:
2311f11c7f63SJim Harris       case SCU_EVENT_SPECIFIC_TASK_TIMEOUT:
2312f11c7f63SJim Harris          io_request = this_controller->io_request_table[index];
2313f11c7f63SJim Harris          if (io_request != SCI_INVALID_HANDLE)
2314f11c7f63SJim Harris          {
2315f11c7f63SJim Harris             scic_sds_io_request_event_handler(io_request, completion_entry);
2316f11c7f63SJim Harris          }
2317f11c7f63SJim Harris          else
2318f11c7f63SJim Harris          {
2319f11c7f63SJim Harris             SCIC_LOG_WARNING((
2320f11c7f63SJim Harris                sci_base_object_get_logger(this_controller),
2321f11c7f63SJim Harris                SCIC_LOG_OBJECT_CONTROLLER |
2322f11c7f63SJim Harris                SCIC_LOG_OBJECT_SMP_IO_REQUEST |
2323f11c7f63SJim Harris                SCIC_LOG_OBJECT_SSP_IO_REQUEST |
2324f11c7f63SJim Harris                SCIC_LOG_OBJECT_STP_IO_REQUEST,
2325f11c7f63SJim Harris                "SCIC Controller 0x%x received event 0x%x for io request object that doesnt exist.\n",
2326f11c7f63SJim Harris                this_controller, completion_entry
2327f11c7f63SJim Harris             ));
2328f11c7f63SJim Harris          }
2329f11c7f63SJim Harris          break;
2330f11c7f63SJim Harris 
2331f11c7f63SJim Harris       case SCU_EVENT_SPECIFIC_IT_NEXUS_TIMEOUT:
2332f11c7f63SJim Harris          device = this_controller->device_table[index];
2333f11c7f63SJim Harris          if (device != SCI_INVALID_HANDLE)
2334f11c7f63SJim Harris          {
2335f11c7f63SJim Harris             scic_sds_remote_device_event_handler(device, completion_entry);
2336f11c7f63SJim Harris          }
2337f11c7f63SJim Harris          else
2338f11c7f63SJim Harris          {
2339f11c7f63SJim Harris             SCIC_LOG_WARNING((
2340f11c7f63SJim Harris                sci_base_object_get_logger(this_controller),
2341f11c7f63SJim Harris                SCIC_LOG_OBJECT_CONTROLLER |
2342f11c7f63SJim Harris                SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
2343f11c7f63SJim Harris                SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
2344f11c7f63SJim Harris                SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
2345f11c7f63SJim Harris                "SCIC Controller 0x%x received event 0x%x for remote device object that doesnt exist.\n",
2346f11c7f63SJim Harris                this_controller, completion_entry
2347f11c7f63SJim Harris             ));
2348f11c7f63SJim Harris          }
2349f11c7f63SJim Harris          break;
2350f11c7f63SJim Harris       }
2351f11c7f63SJim Harris       break;
2352f11c7f63SJim Harris 
2353f11c7f63SJim Harris    case SCU_EVENT_TYPE_BROADCAST_CHANGE:
2354f11c7f63SJim Harris       // direct the broadcast change event to the phy first and then let
2355f11c7f63SJim Harris       // the phy redirect the broadcast change to the port object
2356f11c7f63SJim Harris    case SCU_EVENT_TYPE_ERR_CNT_EVENT:
2357f11c7f63SJim Harris       // direct error counter event to the phy object since that is where
2358f11c7f63SJim Harris       // we get the event notification.  This is a type 4 event.
2359f11c7f63SJim Harris    case SCU_EVENT_TYPE_OSSP_EVENT:
2360f11c7f63SJim Harris       index = SCU_GET_PROTOCOL_ENGINE_INDEX(completion_entry);
2361f11c7f63SJim Harris       phy = &this_controller->phy_table[index];
2362f11c7f63SJim Harris       scic_sds_phy_event_handler(phy, completion_entry);
2363f11c7f63SJim Harris       break;
2364f11c7f63SJim Harris 
2365f11c7f63SJim Harris    case SCU_EVENT_TYPE_RNC_SUSPEND_TX:
2366f11c7f63SJim Harris    case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX:
2367f11c7f63SJim Harris    case SCU_EVENT_TYPE_RNC_OPS_MISC:
2368f11c7f63SJim Harris       if (index < this_controller->remote_node_entries)
2369f11c7f63SJim Harris       {
2370f11c7f63SJim Harris          device = this_controller->device_table[index];
2371f11c7f63SJim Harris 
2372f11c7f63SJim Harris          if (device != NULL)
2373f11c7f63SJim Harris          {
2374f11c7f63SJim Harris             scic_sds_remote_device_event_handler(device, completion_entry);
2375f11c7f63SJim Harris          }
2376f11c7f63SJim Harris       }
2377f11c7f63SJim Harris       else
2378f11c7f63SJim Harris       {
2379f11c7f63SJim Harris          SCIC_LOG_ERROR((
2380f11c7f63SJim Harris             sci_base_object_get_logger(this_controller),
2381f11c7f63SJim Harris             SCIC_LOG_OBJECT_CONTROLLER |
2382f11c7f63SJim Harris             SCIC_LOG_OBJECT_SMP_REMOTE_TARGET |
2383f11c7f63SJim Harris             SCIC_LOG_OBJECT_SSP_REMOTE_TARGET |
2384f11c7f63SJim Harris             SCIC_LOG_OBJECT_STP_REMOTE_TARGET,
2385f11c7f63SJim Harris             "SCIC Controller 0x%x received event 0x%x for remote device object 0x%0x that doesnt exist.\n",
2386f11c7f63SJim Harris             this_controller, completion_entry, index
2387f11c7f63SJim Harris          ));
2388f11c7f63SJim Harris       }
2389f11c7f63SJim Harris       break;
2390f11c7f63SJim Harris 
2391f11c7f63SJim Harris    default:
2392f11c7f63SJim Harris       SCIC_LOG_WARNING((
2393f11c7f63SJim Harris          sci_base_object_get_logger(this_controller),
2394f11c7f63SJim Harris          SCIC_LOG_OBJECT_CONTROLLER,
2395f11c7f63SJim Harris          "SCIC Controller received unknown event code %x\n",
2396f11c7f63SJim Harris          completion_entry
2397f11c7f63SJim Harris       ));
2398f11c7f63SJim Harris       break;
2399f11c7f63SJim Harris    }
2400f11c7f63SJim Harris }
2401f11c7f63SJim Harris 
2402f11c7f63SJim Harris /**
2403f11c7f63SJim Harris  * @brief This method is a private routine for processing the completion
2404f11c7f63SJim Harris  *        queue entries.
2405f11c7f63SJim Harris  *
2406f11c7f63SJim Harris  * @param[in] this_controller
2407f11c7f63SJim Harris  *
2408f11c7f63SJim Harris  * @return none
2409f11c7f63SJim Harris  */
2410f11c7f63SJim Harris static
scic_sds_controller_process_completions(SCIC_SDS_CONTROLLER_T * this_controller)2411f11c7f63SJim Harris void scic_sds_controller_process_completions(
2412f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
2413f11c7f63SJim Harris )
2414f11c7f63SJim Harris {
2415f11c7f63SJim Harris    U32 completion_count = 0;
2416f11c7f63SJim Harris    U32 completion_entry;
2417f11c7f63SJim Harris    U32 get_index;
2418f11c7f63SJim Harris    U32 get_cycle;
2419f11c7f63SJim Harris    U32 event_index;
2420f11c7f63SJim Harris    U32 event_cycle;
2421f11c7f63SJim Harris 
2422f11c7f63SJim Harris    SCIC_LOG_TRACE((
2423f11c7f63SJim Harris       sci_base_object_get_logger(this_controller),
2424f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
2425f11c7f63SJim Harris       "scic_sds_controller_process_completions(0x%x) enter\n",
2426f11c7f63SJim Harris       this_controller
2427f11c7f63SJim Harris    ));
2428f11c7f63SJim Harris 
2429f11c7f63SJim Harris    SCIC_LOG_TRACE((
2430f11c7f63SJim Harris       sci_base_object_get_logger(this_controller),
2431f11c7f63SJim Harris       SCIC_LOG_OBJECT_COMPLETION_QUEUE,
2432453130d9SPedro F. Giffuni       "completion queue beginning get : 0x%08x\n",
2433f11c7f63SJim Harris       this_controller->completion_queue_get
2434f11c7f63SJim Harris    ));
2435f11c7f63SJim Harris 
2436f11c7f63SJim Harris    // Get the component parts of the completion queue
2437f11c7f63SJim Harris    get_index = NORMALIZE_GET_POINTER(this_controller->completion_queue_get);
2438f11c7f63SJim Harris    get_cycle = SMU_CQGR_CYCLE_BIT & this_controller->completion_queue_get;
2439f11c7f63SJim Harris 
2440f11c7f63SJim Harris    event_index = NORMALIZE_EVENT_POINTER(this_controller->completion_queue_get);
2441f11c7f63SJim Harris    event_cycle = SMU_CQGR_EVENT_CYCLE_BIT & this_controller->completion_queue_get;
2442f11c7f63SJim Harris 
2443f11c7f63SJim Harris    while (
2444f11c7f63SJim Harris                NORMALIZE_GET_POINTER_CYCLE_BIT(get_cycle)
2445f11c7f63SJim Harris             == COMPLETION_QUEUE_CYCLE_BIT(this_controller->completion_queue[get_index])
2446f11c7f63SJim Harris          )
2447f11c7f63SJim Harris    {
2448f11c7f63SJim Harris       completion_count++;
2449f11c7f63SJim Harris 
2450f11c7f63SJim Harris       completion_entry = this_controller->completion_queue[get_index];
2451f11c7f63SJim Harris       INCREMENT_COMPLETION_QUEUE_GET(this_controller, get_index, get_cycle);
2452f11c7f63SJim Harris 
2453f11c7f63SJim Harris       SCIC_LOG_TRACE((
2454f11c7f63SJim Harris          sci_base_object_get_logger(this_controller),
2455f11c7f63SJim Harris          SCIC_LOG_OBJECT_COMPLETION_QUEUE,
2456f11c7f63SJim Harris          "completion queue entry : 0x%08x\n",
2457f11c7f63SJim Harris          completion_entry
2458f11c7f63SJim Harris       ));
2459f11c7f63SJim Harris 
2460f11c7f63SJim Harris       switch (SCU_GET_COMPLETION_TYPE(completion_entry))
2461f11c7f63SJim Harris       {
2462f11c7f63SJim Harris       case SCU_COMPLETION_TYPE_TASK:
2463f11c7f63SJim Harris          scic_sds_controller_task_completion(this_controller, completion_entry);
2464f11c7f63SJim Harris          break;
2465f11c7f63SJim Harris 
2466f11c7f63SJim Harris       case SCU_COMPLETION_TYPE_SDMA:
2467f11c7f63SJim Harris          scic_sds_controller_sdma_completion(this_controller, completion_entry);
2468f11c7f63SJim Harris          break;
2469f11c7f63SJim Harris 
2470f11c7f63SJim Harris       case SCU_COMPLETION_TYPE_UFI:
2471f11c7f63SJim Harris          scic_sds_controller_unsolicited_frame(this_controller, completion_entry);
2472f11c7f63SJim Harris          break;
2473f11c7f63SJim Harris 
2474f11c7f63SJim Harris       case SCU_COMPLETION_TYPE_EVENT:
2475f11c7f63SJim Harris          scic_sds_controller_event_completion(this_controller, completion_entry);
2476f11c7f63SJim Harris          break;
2477f11c7f63SJim Harris 
2478f11c7f63SJim Harris       case SCU_COMPLETION_TYPE_NOTIFY:
2479f11c7f63SJim Harris          // Presently we do the same thing with a notify event that we do with the
2480f11c7f63SJim Harris          // other event codes.
2481f11c7f63SJim Harris          INCREMENT_EVENT_QUEUE_GET(this_controller, event_index, event_cycle);
2482f11c7f63SJim Harris          scic_sds_controller_event_completion(this_controller, completion_entry);
2483f11c7f63SJim Harris          break;
2484f11c7f63SJim Harris 
2485f11c7f63SJim Harris       default:
2486f11c7f63SJim Harris          SCIC_LOG_WARNING((
2487f11c7f63SJim Harris             sci_base_object_get_logger(this_controller),
2488f11c7f63SJim Harris             SCIC_LOG_OBJECT_CONTROLLER,
2489f11c7f63SJim Harris             "SCIC Controller received unknown completion type %x\n",
2490f11c7f63SJim Harris             completion_entry
2491f11c7f63SJim Harris          ));
2492f11c7f63SJim Harris          break;
2493f11c7f63SJim Harris       }
2494f11c7f63SJim Harris    }
2495f11c7f63SJim Harris 
2496f11c7f63SJim Harris    // Update the get register if we completed one or more entries
2497f11c7f63SJim Harris    if (completion_count > 0)
2498f11c7f63SJim Harris    {
2499f11c7f63SJim Harris       this_controller->completion_queue_get =
2500f11c7f63SJim Harris            SMU_CQGR_GEN_BIT(ENABLE)
2501f11c7f63SJim Harris          | SMU_CQGR_GEN_BIT(EVENT_ENABLE)
2502f11c7f63SJim Harris          | event_cycle | SMU_CQGR_GEN_VAL(EVENT_POINTER, event_index)
2503f11c7f63SJim Harris          | get_cycle   | SMU_CQGR_GEN_VAL(POINTER, get_index)  ;
2504f11c7f63SJim Harris 
2505f11c7f63SJim Harris       SMU_CQGR_WRITE(this_controller, this_controller->completion_queue_get);
2506f11c7f63SJim Harris    }
2507f11c7f63SJim Harris 
2508f11c7f63SJim Harris    SCIC_LOG_TRACE((
2509f11c7f63SJim Harris       sci_base_object_get_logger(this_controller),
2510f11c7f63SJim Harris       SCIC_LOG_OBJECT_COMPLETION_QUEUE,
2511f11c7f63SJim Harris       "completion queue ending get : 0x%08x\n",
2512f11c7f63SJim Harris       this_controller->completion_queue_get
2513f11c7f63SJim Harris    ));
2514f11c7f63SJim Harris 
2515f11c7f63SJim Harris }
2516f11c7f63SJim Harris 
2517f11c7f63SJim Harris /**
2518f11c7f63SJim Harris  * @brief This method is a private routine for processing the completion
2519f11c7f63SJim Harris  *        queue entries.
2520f11c7f63SJim Harris  *
2521f11c7f63SJim Harris  * @param[in] this_controller
2522f11c7f63SJim Harris  *
2523f11c7f63SJim Harris  * @return none
2524f11c7f63SJim Harris  */
2525f11c7f63SJim Harris static
scic_sds_controller_transitioned_process_completions(SCIC_SDS_CONTROLLER_T * this_controller)2526f11c7f63SJim Harris void scic_sds_controller_transitioned_process_completions(
2527f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T * this_controller
2528f11c7f63SJim Harris )
2529f11c7f63SJim Harris {
2530f11c7f63SJim Harris    U32 completion_count = 0;
2531f11c7f63SJim Harris    U32 completion_entry;
2532f11c7f63SJim Harris    U32 get_index;
2533f11c7f63SJim Harris    U32 get_cycle;
2534f11c7f63SJim Harris    U32 event_index;
2535f11c7f63SJim Harris    U32 event_cycle;
2536f11c7f63SJim Harris 
2537f11c7f63SJim Harris    SCIC_LOG_TRACE((
2538f11c7f63SJim Harris       sci_base_object_get_logger(this_controller),
2539f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
2540f11c7f63SJim Harris       "scic_sds_controller_transitioned_process_completions(0x%x) enter\n",
2541f11c7f63SJim Harris       this_controller
2542f11c7f63SJim Harris    ));
2543f11c7f63SJim Harris 
2544f11c7f63SJim Harris    SCIC_LOG_TRACE((
2545f11c7f63SJim Harris       sci_base_object_get_logger(this_controller),
2546f11c7f63SJim Harris       SCIC_LOG_OBJECT_COMPLETION_QUEUE,
2547453130d9SPedro F. Giffuni       "completion queue beginning get : 0x%08x\n",
2548f11c7f63SJim Harris       this_controller->completion_queue_get
2549f11c7f63SJim Harris    ));
2550f11c7f63SJim Harris 
2551f11c7f63SJim Harris    // Get the component parts of the completion queue
2552f11c7f63SJim Harris    get_index = NORMALIZE_GET_POINTER(this_controller->completion_queue_get);
2553f11c7f63SJim Harris    get_cycle = SMU_CQGR_CYCLE_BIT & this_controller->completion_queue_get;
2554f11c7f63SJim Harris 
2555f11c7f63SJim Harris    event_index = NORMALIZE_EVENT_POINTER(this_controller->completion_queue_get);
2556f11c7f63SJim Harris    event_cycle = SMU_CQGR_EVENT_CYCLE_BIT & this_controller->completion_queue_get;
2557f11c7f63SJim Harris 
2558f11c7f63SJim Harris    while (
2559f11c7f63SJim Harris                NORMALIZE_GET_POINTER_CYCLE_BIT(get_cycle)
2560f11c7f63SJim Harris             == COMPLETION_QUEUE_CYCLE_BIT(
2561f11c7f63SJim Harris                   this_controller->completion_queue[get_index])
2562f11c7f63SJim Harris          )
2563f11c7f63SJim Harris    {
2564f11c7f63SJim Harris       completion_count++;
2565f11c7f63SJim Harris 
2566f11c7f63SJim Harris       completion_entry = this_controller->completion_queue[get_index];
2567f11c7f63SJim Harris       INCREMENT_COMPLETION_QUEUE_GET(this_controller, get_index, get_cycle);
2568f11c7f63SJim Harris 
2569f11c7f63SJim Harris       SCIC_LOG_TRACE((
2570f11c7f63SJim Harris          sci_base_object_get_logger(this_controller),
2571f11c7f63SJim Harris          SCIC_LOG_OBJECT_COMPLETION_QUEUE,
2572f11c7f63SJim Harris          "completion queue entry : 0x%08x\n",
2573f11c7f63SJim Harris          completion_entry
2574f11c7f63SJim Harris       ));
2575f11c7f63SJim Harris 
2576f11c7f63SJim Harris       switch (SCU_GET_COMPLETION_TYPE(completion_entry))
2577f11c7f63SJim Harris       {
2578f11c7f63SJim Harris       case SCU_COMPLETION_TYPE_TASK:
2579f11c7f63SJim Harris          scic_sds_controller_task_completion(this_controller, completion_entry);
2580f11c7f63SJim Harris       break;
2581f11c7f63SJim Harris 
2582f11c7f63SJim Harris       case SCU_COMPLETION_TYPE_NOTIFY:
2583f11c7f63SJim Harris          INCREMENT_EVENT_QUEUE_GET(this_controller, event_index, event_cycle);
2584f11c7f63SJim Harris          // Fall-through
2585f11c7f63SJim Harris 
2586f11c7f63SJim Harris       case SCU_COMPLETION_TYPE_EVENT:
2587f11c7f63SJim Harris       case SCU_COMPLETION_TYPE_SDMA:
2588f11c7f63SJim Harris       case SCU_COMPLETION_TYPE_UFI:
2589f11c7f63SJim Harris       default:
2590f11c7f63SJim Harris          SCIC_LOG_WARNING((
2591f11c7f63SJim Harris             sci_base_object_get_logger(this_controller),
2592f11c7f63SJim Harris             SCIC_LOG_OBJECT_CONTROLLER,
2593f11c7f63SJim Harris             "SCIC Controller ignoring completion type %x\n",
2594f11c7f63SJim Harris             completion_entry
2595f11c7f63SJim Harris          ));
2596f11c7f63SJim Harris       break;
2597f11c7f63SJim Harris       }
2598f11c7f63SJim Harris    }
2599f11c7f63SJim Harris 
2600f11c7f63SJim Harris    // Update the get register if we completed one or more entries
2601f11c7f63SJim Harris    if (completion_count > 0)
2602f11c7f63SJim Harris    {
2603f11c7f63SJim Harris       this_controller->completion_queue_get =
2604f11c7f63SJim Harris            SMU_CQGR_GEN_BIT(ENABLE)
2605f11c7f63SJim Harris          | SMU_CQGR_GEN_BIT(EVENT_ENABLE)
2606f11c7f63SJim Harris          | event_cycle | SMU_CQGR_GEN_VAL(EVENT_POINTER, event_index)
2607f11c7f63SJim Harris          | get_cycle   | SMU_CQGR_GEN_VAL(POINTER, get_index)  ;
2608f11c7f63SJim Harris 
2609f11c7f63SJim Harris       SMU_CQGR_WRITE(this_controller, this_controller->completion_queue_get);
2610f11c7f63SJim Harris    }
2611f11c7f63SJim Harris 
2612f11c7f63SJim Harris    SCIC_LOG_TRACE((
2613f11c7f63SJim Harris       sci_base_object_get_logger(this_controller),
2614f11c7f63SJim Harris       SCIC_LOG_OBJECT_COMPLETION_QUEUE,
2615f11c7f63SJim Harris       "completion queue ending get : 0x%08x\n",
2616f11c7f63SJim Harris       this_controller->completion_queue_get
2617f11c7f63SJim Harris    ));
2618f11c7f63SJim Harris }
2619f11c7f63SJim Harris 
2620f11c7f63SJim Harris //****************************************************************************-
2621f11c7f63SJim Harris //* SCIC SDS Controller Interrupt and Completion functions
2622f11c7f63SJim Harris //****************************************************************************-
2623f11c7f63SJim Harris 
2624f11c7f63SJim Harris /**
2625f11c7f63SJim Harris  * @brief This method provides standard (common) processing of interrupts
2626f11c7f63SJim Harris  *        for polling and legacy based interrupts.
2627f11c7f63SJim Harris  *
2628f11c7f63SJim Harris  * @param[in] controller
2629f11c7f63SJim Harris  * @param[in] interrupt_status
2630f11c7f63SJim Harris  *
2631f11c7f63SJim Harris  * @return This method returns a boolean (BOOL) indication as to
2632f11c7f63SJim Harris  *         whether an completions are pending to be processed.
2633f11c7f63SJim Harris  * @retval TRUE if an interrupt is to be processed
2634f11c7f63SJim Harris  * @retval FALSE if no interrupt was pending
2635f11c7f63SJim Harris  */
2636f11c7f63SJim Harris static
scic_sds_controller_standard_interrupt_handler(SCIC_SDS_CONTROLLER_T * this_controller,U32 interrupt_status)2637f11c7f63SJim Harris BOOL scic_sds_controller_standard_interrupt_handler(
2638f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller,
2639f11c7f63SJim Harris    U32                    interrupt_status
2640f11c7f63SJim Harris )
2641f11c7f63SJim Harris {
2642f11c7f63SJim Harris    BOOL  is_completion_needed = FALSE;
2643f11c7f63SJim Harris 
2644f11c7f63SJim Harris    SCIC_LOG_TRACE((
2645f11c7f63SJim Harris       sci_base_object_get_logger(this_controller),
2646f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
2647f11c7f63SJim Harris       "scic_sds_controller_standard_interrupt_handler(0x%d,0x%d) enter\n",
2648f11c7f63SJim Harris       this_controller, interrupt_status
2649f11c7f63SJim Harris    ));
2650f11c7f63SJim Harris 
2651f11c7f63SJim Harris    if (
2652f11c7f63SJim Harris          (interrupt_status & SMU_ISR_QUEUE_ERROR)
2653f11c7f63SJim Harris       || (
2654f11c7f63SJim Harris             (interrupt_status & SMU_ISR_QUEUE_SUSPEND)
2655f11c7f63SJim Harris          && (!scic_sds_controller_completion_queue_has_entries(this_controller))
2656f11c7f63SJim Harris          )
2657f11c7f63SJim Harris       )
2658f11c7f63SJim Harris    {
2659f11c7f63SJim Harris       // We have a fatal error on the read of the completion queue bar
2660f11c7f63SJim Harris       // OR
2661f11c7f63SJim Harris       // We have a fatal error there is nothing in the completion queue
2662f11c7f63SJim Harris       // but we have a report from the hardware that the queue is full
2663f11c7f63SJim Harris       /// @todo how do we request the a controller reset
2664f11c7f63SJim Harris       is_completion_needed = TRUE;
2665f11c7f63SJim Harris       this_controller->encountered_fatal_error = TRUE;
2666f11c7f63SJim Harris    }
2667f11c7f63SJim Harris 
2668f11c7f63SJim Harris    if (scic_sds_controller_completion_queue_has_entries(this_controller))
2669f11c7f63SJim Harris    {
2670f11c7f63SJim Harris       is_completion_needed = TRUE;
2671f11c7f63SJim Harris    }
2672f11c7f63SJim Harris 
2673f11c7f63SJim Harris    return is_completion_needed;
2674f11c7f63SJim Harris }
2675f11c7f63SJim Harris 
2676f11c7f63SJim Harris /**
2677f11c7f63SJim Harris  * @brief This is the method provided to handle polling for interrupts
2678f11c7f63SJim Harris  *        for the controller object.
2679f11c7f63SJim Harris  *
2680f11c7f63SJim Harris  * @param[in] controller
2681f11c7f63SJim Harris  *
2682f11c7f63SJim Harris  * @return BOOL
2683f11c7f63SJim Harris  * @retval TRUE if an interrupt is to be processed
2684f11c7f63SJim Harris  * @retval FALSE if no interrupt was pending
2685f11c7f63SJim Harris  */
2686f11c7f63SJim Harris static
scic_sds_controller_polling_interrupt_handler(SCI_CONTROLLER_HANDLE_T controller)2687f11c7f63SJim Harris BOOL scic_sds_controller_polling_interrupt_handler(
2688f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller
2689f11c7f63SJim Harris )
2690f11c7f63SJim Harris {
2691f11c7f63SJim Harris    U32                    interrupt_status;
2692f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller = (SCIC_SDS_CONTROLLER_T*)controller;
2693f11c7f63SJim Harris 
2694f11c7f63SJim Harris    SCIC_LOG_TRACE((
2695f11c7f63SJim Harris       sci_base_object_get_logger(controller),
2696f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
2697f11c7f63SJim Harris       "scic_sds_controller_polling_interrupt_handler(0x%d) enter\n",
2698f11c7f63SJim Harris       controller
2699f11c7f63SJim Harris    ));
2700f11c7f63SJim Harris 
2701f11c7f63SJim Harris    /*
2702f11c7f63SJim Harris     * In INTERRUPT_POLLING_MODE we exit the interrupt handler if the hardware
2703f11c7f63SJim Harris     * indicates nothing is pending. Since we are not being called from a real
2704f11c7f63SJim Harris     * interrupt, we don't want to confuse the hardware by servicing the
2705f11c7f63SJim Harris     * completion queue before the hardware indicates it is ready. We'll
2706f11c7f63SJim Harris     * simply wait for another polling interval and check again.
2707f11c7f63SJim Harris     */
2708f11c7f63SJim Harris    interrupt_status = SMU_ISR_READ(this_controller);
2709f11c7f63SJim Harris    if ((interrupt_status &
2710f11c7f63SJim Harris          (SMU_ISR_COMPLETION |
2711f11c7f63SJim Harris           SMU_ISR_QUEUE_ERROR |
2712f11c7f63SJim Harris           SMU_ISR_QUEUE_SUSPEND)) == 0)
2713f11c7f63SJim Harris    {
2714f11c7f63SJim Harris       return FALSE;
2715f11c7f63SJim Harris    }
2716f11c7f63SJim Harris 
2717f11c7f63SJim Harris    return scic_sds_controller_standard_interrupt_handler(
2718f11c7f63SJim Harris              controller, interrupt_status
2719f11c7f63SJim Harris           );
2720f11c7f63SJim Harris }
2721f11c7f63SJim Harris 
2722f11c7f63SJim Harris /**
2723f11c7f63SJim Harris  * @brief This is the method provided to handle completions when interrupt
2724f11c7f63SJim Harris  *        polling is in use.
2725f11c7f63SJim Harris  *
2726f11c7f63SJim Harris  * @param[in] controller
2727f11c7f63SJim Harris  *
2728f11c7f63SJim Harris  * @return none
2729f11c7f63SJim Harris  */
2730f11c7f63SJim Harris static
scic_sds_controller_polling_completion_handler(SCI_CONTROLLER_HANDLE_T controller)2731f11c7f63SJim Harris void scic_sds_controller_polling_completion_handler(
2732f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller
2733f11c7f63SJim Harris )
2734f11c7f63SJim Harris {
2735f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
2736f11c7f63SJim Harris 
2737f11c7f63SJim Harris    SCIC_LOG_TRACE((
2738f11c7f63SJim Harris       sci_base_object_get_logger(controller),
2739f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
2740f11c7f63SJim Harris       "scic_sds_controller_polling_completion_handler(0x%d) enter\n",
2741f11c7f63SJim Harris       controller
2742f11c7f63SJim Harris    ));
2743f11c7f63SJim Harris 
2744f11c7f63SJim Harris    if (this_controller->encountered_fatal_error == TRUE)
2745f11c7f63SJim Harris    {
2746f11c7f63SJim Harris       SCIC_LOG_ERROR((
2747f11c7f63SJim Harris          sci_base_object_get_logger(this_controller),
2748f11c7f63SJim Harris          SCIC_LOG_OBJECT_CONTROLLER,
2749f11c7f63SJim Harris          "SCIC Controller has encountered a fatal error.\n"
2750f11c7f63SJim Harris       ));
2751f11c7f63SJim Harris 
2752f11c7f63SJim Harris       sci_base_state_machine_change_state(
2753f11c7f63SJim Harris          scic_sds_controller_get_base_state_machine(this_controller),
2754f11c7f63SJim Harris          SCI_BASE_CONTROLLER_STATE_FAILED
2755f11c7f63SJim Harris       );
2756f11c7f63SJim Harris    }
2757f11c7f63SJim Harris    else if (scic_sds_controller_completion_queue_has_entries(this_controller))
2758f11c7f63SJim Harris    {
2759f11c7f63SJim Harris       if (this_controller->restrict_completions == FALSE)
2760f11c7f63SJim Harris          scic_sds_controller_process_completions(this_controller);
2761f11c7f63SJim Harris       else
2762f11c7f63SJim Harris          scic_sds_controller_transitioned_process_completions(this_controller);
2763f11c7f63SJim Harris    }
2764f11c7f63SJim Harris 
2765f11c7f63SJim Harris    /*
2766f11c7f63SJim Harris     * The interrupt handler does not adjust the CQ's
2767f11c7f63SJim Harris     * get pointer.  So, SCU's INTx pin stays asserted during the
2768f11c7f63SJim Harris     * interrupt handler even though it tries to clear the interrupt
2769f11c7f63SJim Harris     * source.  Therefore, the completion handler must ensure that the
2770f11c7f63SJim Harris     * interrupt source is cleared.  Otherwise, we get a spurious
2771f11c7f63SJim Harris     * interrupt for which the interrupt handler will not issue a
2772f11c7f63SJim Harris     * corresponding completion event. Also, we unmask interrupts.
2773f11c7f63SJim Harris     */
2774f11c7f63SJim Harris    SMU_ISR_WRITE(
2775f11c7f63SJim Harris       this_controller,
2776f11c7f63SJim Harris       (U32)(SMU_ISR_COMPLETION | SMU_ISR_QUEUE_ERROR | SMU_ISR_QUEUE_SUSPEND)
2777f11c7f63SJim Harris    );
2778f11c7f63SJim Harris }
2779f11c7f63SJim Harris 
2780f11c7f63SJim Harris #if !defined(DISABLE_INTERRUPTS)
2781f11c7f63SJim Harris /**
2782f11c7f63SJim Harris  * @brief This is the method provided to handle legacy interrupts for the
2783f11c7f63SJim Harris  *        controller object.
2784f11c7f63SJim Harris  *
2785f11c7f63SJim Harris  * @param[in] controller
2786f11c7f63SJim Harris  *
2787f11c7f63SJim Harris  * @return BOOL
2788f11c7f63SJim Harris  * @retval TRUE if an interrupt is processed
2789f11c7f63SJim Harris  *         FALSE if no interrupt was processed
2790f11c7f63SJim Harris  */
2791f11c7f63SJim Harris static
scic_sds_controller_legacy_interrupt_handler(SCI_CONTROLLER_HANDLE_T controller)2792f11c7f63SJim Harris BOOL scic_sds_controller_legacy_interrupt_handler(
2793f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller
2794f11c7f63SJim Harris )
2795f11c7f63SJim Harris {
2796f11c7f63SJim Harris    U32                    interrupt_status;
2797f11c7f63SJim Harris    BOOL                   is_completion_needed;
2798f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller = (SCIC_SDS_CONTROLLER_T*)controller;
2799f11c7f63SJim Harris 
2800f11c7f63SJim Harris    interrupt_status     = SMU_ISR_READ(this_controller);
2801f11c7f63SJim Harris    is_completion_needed = scic_sds_controller_standard_interrupt_handler(
2802f11c7f63SJim Harris                              this_controller, interrupt_status
2803f11c7f63SJim Harris                           );
2804f11c7f63SJim Harris 
2805f11c7f63SJim Harris    return is_completion_needed;
2806f11c7f63SJim Harris }
2807f11c7f63SJim Harris 
2808f11c7f63SJim Harris 
2809f11c7f63SJim Harris /**
2810f11c7f63SJim Harris  * @brief This is the method provided to handle legacy completions it is
2811f11c7f63SJim Harris  *        expected that the SCI User will call this completion handler
2812f11c7f63SJim Harris  *        anytime the interrupt handler reports that it has handled an
2813f11c7f63SJim Harris  *        interrupt.
2814f11c7f63SJim Harris  *
2815f11c7f63SJim Harris  * @param[in] controller
2816f11c7f63SJim Harris  *
2817f11c7f63SJim Harris  * @return none
2818f11c7f63SJim Harris  */
2819f11c7f63SJim Harris static
scic_sds_controller_legacy_completion_handler(SCI_CONTROLLER_HANDLE_T controller)2820f11c7f63SJim Harris void scic_sds_controller_legacy_completion_handler(
2821f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller
2822f11c7f63SJim Harris )
2823f11c7f63SJim Harris {
2824f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
2825f11c7f63SJim Harris 
2826f11c7f63SJim Harris    SCIC_LOG_TRACE((
2827f11c7f63SJim Harris       sci_base_object_get_logger(controller),
2828f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
2829f11c7f63SJim Harris       "scic_sds_controller_legacy_completion_handler(0x%d) enter\n",
2830f11c7f63SJim Harris       controller
2831f11c7f63SJim Harris    ));
2832f11c7f63SJim Harris 
2833f11c7f63SJim Harris    scic_sds_controller_polling_completion_handler(controller);
2834f11c7f63SJim Harris 
2835f11c7f63SJim Harris    SMU_IMR_WRITE(this_controller, 0x00000000);
2836f11c7f63SJim Harris 
2837f11c7f63SJim Harris #ifdef IMR_READ_FENCE
2838f11c7f63SJim Harris    {
2839f11c7f63SJim Harris       volatile U32 int_mask_value = 0;
2840f11c7f63SJim Harris       ULONG count = 0;
2841f11c7f63SJim Harris 
2842f11c7f63SJim Harris       /*
2843f11c7f63SJim Harris        * Temporary code since we have seen with legacy interrupts
2844f11c7f63SJim Harris        * that interrupts are still masked after clearing the mask
2845f11c7f63SJim Harris        * above. This may be an Arlington problem or it may be an
2846f11c7f63SJim Harris        * old driver problem.  Presently this code is turned off
2847f11c7f63SJim Harris        * since we have not seen this problem recently.
2848f11c7f63SJim Harris        */
2849f11c7f63SJim Harris       do
2850f11c7f63SJim Harris       {
2851f11c7f63SJim Harris          int_mask_value = SMU_IMR_READ(this_controler);
2852f11c7f63SJim Harris 
2853f11c7f63SJim Harris          if (count++ > 10)
2854f11c7f63SJim Harris          {
2855f11c7f63SJim Harris             #ifdef ALLOW_ENTER_DEBUGGER
2856f11c7f63SJim Harris             __debugbreak();
2857f11c7f63SJim Harris             #endif
2858f11c7f63SJim Harris             break;
2859f11c7f63SJim Harris          }
2860f11c7f63SJim Harris       } while (int_mask_value != 0);
2861f11c7f63SJim Harris    }
2862f11c7f63SJim Harris #endif
2863f11c7f63SJim Harris }
2864f11c7f63SJim Harris 
2865f11c7f63SJim Harris /**
2866f11c7f63SJim Harris  * @brief This is the method provided to handle an MSIX interrupt message
2867f11c7f63SJim Harris  *        when there is just a single MSIX message being provided by the
2868f11c7f63SJim Harris  *        hardware.  This mode of operation is single vector mode.
2869f11c7f63SJim Harris  *
2870f11c7f63SJim Harris  * @param[in] controller
2871f11c7f63SJim Harris  *
2872f11c7f63SJim Harris  * @return BOOL
2873f11c7f63SJim Harris  * @retval TRUE if an interrupt is processed
2874f11c7f63SJim Harris  *         FALSE if no interrupt was processed
2875f11c7f63SJim Harris  */
2876f11c7f63SJim Harris static
scic_sds_controller_single_vector_interrupt_handler(SCI_CONTROLLER_HANDLE_T controller)2877f11c7f63SJim Harris BOOL scic_sds_controller_single_vector_interrupt_handler(
2878f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller
2879f11c7f63SJim Harris )
2880f11c7f63SJim Harris {
2881f11c7f63SJim Harris    U32 interrupt_status;
2882f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
2883f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
2884f11c7f63SJim Harris 
2885f11c7f63SJim Harris    // Mask the interrupts
2886f11c7f63SJim Harris    // There is a race in the hardware that could cause us not to be notified
2887f11c7f63SJim Harris    // of an interrupt completion if we do not take this step.  We will unmask
2888f11c7f63SJim Harris    // the interrupts in the completion routine.
2889f11c7f63SJim Harris    SMU_IMR_WRITE(this_controller, 0xFFFFFFFF);
2890f11c7f63SJim Harris 
2891f11c7f63SJim Harris    interrupt_status = SMU_ISR_READ(this_controller);
2892f11c7f63SJim Harris    interrupt_status &= (SMU_ISR_QUEUE_ERROR | SMU_ISR_QUEUE_SUSPEND);
2893f11c7f63SJim Harris 
2894f11c7f63SJim Harris    if (
2895f11c7f63SJim Harris            (interrupt_status == 0)
2896f11c7f63SJim Harris         && scic_sds_controller_completion_queue_has_entries(this_controller)
2897f11c7f63SJim Harris       )
2898f11c7f63SJim Harris    {
2899f11c7f63SJim Harris       // There is at least one completion queue entry to process so we can
2900f11c7f63SJim Harris       // return a success and ignore for now the case of an error interrupt
2901f11c7f63SJim Harris       SMU_ISR_WRITE(this_controller, SMU_ISR_COMPLETION);
2902f11c7f63SJim Harris 
2903f11c7f63SJim Harris       return TRUE;
2904f11c7f63SJim Harris    }
2905f11c7f63SJim Harris 
2906f11c7f63SJim Harris 
2907f11c7f63SJim Harris    if (interrupt_status != 0)
2908f11c7f63SJim Harris    {
2909f11c7f63SJim Harris       // There is an error interrupt pending so let it through and handle
2910f11c7f63SJim Harris       // in the callback
2911f11c7f63SJim Harris       return TRUE;
2912f11c7f63SJim Harris    }
2913f11c7f63SJim Harris 
2914f11c7f63SJim Harris    // Clear any offending interrupts since we could not find any to handle
2915f11c7f63SJim Harris    // and unmask them all
2916f11c7f63SJim Harris    SMU_ISR_WRITE(this_controller, 0x00000000);
2917f11c7f63SJim Harris    SMU_IMR_WRITE(this_controller, 0x00000000);
2918f11c7f63SJim Harris 
2919f11c7f63SJim Harris    return FALSE;
2920f11c7f63SJim Harris }
2921f11c7f63SJim Harris 
2922f11c7f63SJim Harris /**
2923f11c7f63SJim Harris  * @brief This is the method provided to handle completions for a single
2924f11c7f63SJim Harris  *        MSIX message.
2925f11c7f63SJim Harris  *
2926f11c7f63SJim Harris  * @param[in] controller
2927f11c7f63SJim Harris  */
2928f11c7f63SJim Harris static
scic_sds_controller_single_vector_completion_handler(SCI_CONTROLLER_HANDLE_T controller)2929f11c7f63SJim Harris void scic_sds_controller_single_vector_completion_handler(
2930f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller
2931f11c7f63SJim Harris )
2932f11c7f63SJim Harris {
2933f11c7f63SJim Harris    U32 interrupt_status;
2934f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
2935f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
2936f11c7f63SJim Harris 
2937f11c7f63SJim Harris    SCIC_LOG_TRACE((
2938f11c7f63SJim Harris       sci_base_object_get_logger(controller),
2939f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
2940f11c7f63SJim Harris       "scic_sds_controller_single_vector_completion_handler(0x%d) enter\n",
2941f11c7f63SJim Harris       controller
2942f11c7f63SJim Harris    ));
2943f11c7f63SJim Harris 
2944f11c7f63SJim Harris    interrupt_status = SMU_ISR_READ(this_controller);
2945f11c7f63SJim Harris    interrupt_status &= (SMU_ISR_QUEUE_ERROR | SMU_ISR_QUEUE_SUSPEND);
2946f11c7f63SJim Harris 
2947f11c7f63SJim Harris    if (interrupt_status & SMU_ISR_QUEUE_ERROR)
2948f11c7f63SJim Harris    {
2949f11c7f63SJim Harris       SCIC_LOG_ERROR((
2950f11c7f63SJim Harris          sci_base_object_get_logger(this_controller),
2951f11c7f63SJim Harris          SCIC_LOG_OBJECT_CONTROLLER,
2952f11c7f63SJim Harris          "SCIC Controller has encountered a fatal error.\n"
2953f11c7f63SJim Harris       ));
2954f11c7f63SJim Harris 
2955f11c7f63SJim Harris       // We have a fatal condition and must reset the controller
2956f11c7f63SJim Harris       // Leave the interrupt mask in place and get the controller reset
2957f11c7f63SJim Harris       sci_base_state_machine_change_state(
2958f11c7f63SJim Harris          scic_sds_controller_get_base_state_machine(this_controller),
2959f11c7f63SJim Harris          SCI_BASE_CONTROLLER_STATE_FAILED
2960f11c7f63SJim Harris       );
2961f11c7f63SJim Harris       return;
2962f11c7f63SJim Harris    }
2963f11c7f63SJim Harris 
2964f11c7f63SJim Harris    if (
2965f11c7f63SJim Harris            (interrupt_status & SMU_ISR_QUEUE_SUSPEND)
2966f11c7f63SJim Harris         && !scic_sds_controller_completion_queue_has_entries(this_controller)
2967f11c7f63SJim Harris       )
2968f11c7f63SJim Harris    {
2969f11c7f63SJim Harris       SCIC_LOG_ERROR((
2970f11c7f63SJim Harris          sci_base_object_get_logger(this_controller),
2971f11c7f63SJim Harris          SCIC_LOG_OBJECT_CONTROLLER,
2972f11c7f63SJim Harris          "SCIC Controller has encountered a fatal error.\n"
2973f11c7f63SJim Harris       ));
2974f11c7f63SJim Harris 
2975f11c7f63SJim Harris       // We have a fatal condtion and must reset the controller
2976f11c7f63SJim Harris       // Leave the interrupt mask in place and get the controller reset
2977f11c7f63SJim Harris       sci_base_state_machine_change_state(
2978f11c7f63SJim Harris          scic_sds_controller_get_base_state_machine(this_controller),
2979f11c7f63SJim Harris          SCI_BASE_CONTROLLER_STATE_FAILED
2980f11c7f63SJim Harris       );
2981f11c7f63SJim Harris       return;
2982f11c7f63SJim Harris    }
2983f11c7f63SJim Harris 
2984f11c7f63SJim Harris    if (scic_sds_controller_completion_queue_has_entries(this_controller))
2985f11c7f63SJim Harris    {
2986f11c7f63SJim Harris       scic_sds_controller_process_completions(this_controller);
2987f11c7f63SJim Harris 
2988f11c7f63SJim Harris       // We dont care which interrupt got us to processing the completion queu
2989f11c7f63SJim Harris       // so clear them both.
2990f11c7f63SJim Harris       SMU_ISR_WRITE(
2991f11c7f63SJim Harris          this_controller,
2992f11c7f63SJim Harris          (SMU_ISR_COMPLETION | SMU_ISR_QUEUE_SUSPEND)
2993f11c7f63SJim Harris       );
2994f11c7f63SJim Harris    }
2995f11c7f63SJim Harris 
2996f11c7f63SJim Harris    SMU_IMR_WRITE(this_controller, 0x00000000);
2997f11c7f63SJim Harris }
2998f11c7f63SJim Harris 
2999f11c7f63SJim Harris /**
3000f11c7f63SJim Harris  * @brief This is the method provided to handle a MSIX message for a normal
3001f11c7f63SJim Harris  *        completion.
3002f11c7f63SJim Harris  *
3003f11c7f63SJim Harris  * @param[in] controller
3004f11c7f63SJim Harris  *
3005f11c7f63SJim Harris  * @return BOOL
3006f11c7f63SJim Harris  * @retval TRUE if an interrupt is processed
3007f11c7f63SJim Harris  *         FALSE if no interrupt was processed
3008f11c7f63SJim Harris  */
3009f11c7f63SJim Harris static
scic_sds_controller_normal_vector_interrupt_handler(SCI_CONTROLLER_HANDLE_T controller)3010f11c7f63SJim Harris BOOL scic_sds_controller_normal_vector_interrupt_handler(
3011f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller
3012f11c7f63SJim Harris )
3013f11c7f63SJim Harris {
3014f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
3015f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
3016f11c7f63SJim Harris 
3017f11c7f63SJim Harris    if (scic_sds_controller_completion_queue_has_entries(this_controller))
3018f11c7f63SJim Harris    {
3019f11c7f63SJim Harris       return TRUE;
3020f11c7f63SJim Harris    }
3021f11c7f63SJim Harris    else
3022f11c7f63SJim Harris    {
3023f11c7f63SJim Harris       // we have a spurious interrupt it could be that we have already
3024f11c7f63SJim Harris       // emptied the completion queue from a previous interrupt
3025f11c7f63SJim Harris       SMU_ISR_WRITE(this_controller, SMU_ISR_COMPLETION);
3026f11c7f63SJim Harris 
3027f11c7f63SJim Harris       // There is a race in the hardware that could cause us not to be notified
3028f11c7f63SJim Harris       // of an interrupt completion if we do not take this step.  We will mask
3029f11c7f63SJim Harris       // then unmask the interrupts so if there is another interrupt pending
3030f11c7f63SJim Harris       // the clearing of the interrupt source we get the next interrupt message.
3031f11c7f63SJim Harris       SMU_IMR_WRITE(this_controller, 0xFF000000);
3032f11c7f63SJim Harris       SMU_IMR_WRITE(this_controller, 0x00000000);
3033f11c7f63SJim Harris    }
3034f11c7f63SJim Harris 
3035f11c7f63SJim Harris    return FALSE;
3036f11c7f63SJim Harris }
3037f11c7f63SJim Harris 
3038f11c7f63SJim Harris /**
3039f11c7f63SJim Harris  * @brief This is the method provided to handle the completions for a
3040f11c7f63SJim Harris  *        normal MSIX message.
3041f11c7f63SJim Harris  *
3042f11c7f63SJim Harris  * @param[in] controller
3043f11c7f63SJim Harris  */
3044f11c7f63SJim Harris static
scic_sds_controller_normal_vector_completion_handler(SCI_CONTROLLER_HANDLE_T controller)3045f11c7f63SJim Harris void scic_sds_controller_normal_vector_completion_handler(
3046f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller
3047f11c7f63SJim Harris )
3048f11c7f63SJim Harris {
3049f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
3050f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
3051f11c7f63SJim Harris 
3052f11c7f63SJim Harris    SCIC_LOG_TRACE((
3053f11c7f63SJim Harris       sci_base_object_get_logger(controller),
3054f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
3055f11c7f63SJim Harris       "scic_sds_controller_normal_vector_completion_handler(0x%d) enter\n",
3056f11c7f63SJim Harris       controller
3057f11c7f63SJim Harris    ));
3058f11c7f63SJim Harris 
3059f11c7f63SJim Harris    // Empty out the completion queue
3060f11c7f63SJim Harris    if (scic_sds_controller_completion_queue_has_entries(this_controller))
3061f11c7f63SJim Harris    {
3062f11c7f63SJim Harris       scic_sds_controller_process_completions(this_controller);
3063f11c7f63SJim Harris    }
3064f11c7f63SJim Harris 
3065f11c7f63SJim Harris    // Clear the interrupt and enable all interrupts again
3066f11c7f63SJim Harris    SMU_ISR_WRITE(this_controller, SMU_ISR_COMPLETION);
3067f11c7f63SJim Harris    // Could we write the value of SMU_ISR_COMPLETION?
3068f11c7f63SJim Harris    SMU_IMR_WRITE(this_controller, 0xFF000000);
3069f11c7f63SJim Harris    SMU_IMR_WRITE(this_controller, 0x00000000);
3070f11c7f63SJim Harris }
3071f11c7f63SJim Harris 
3072f11c7f63SJim Harris /**
3073f11c7f63SJim Harris  * @brief This is the method provided to handle the error MSIX message
3074f11c7f63SJim Harris  *        interrupt.  This is the normal operating mode for the hardware if
3075f11c7f63SJim Harris  *        MSIX is enabled.
3076f11c7f63SJim Harris  *
3077f11c7f63SJim Harris  * @param[in] controller
3078f11c7f63SJim Harris  *
3079f11c7f63SJim Harris  * @return BOOL
3080f11c7f63SJim Harris  * @retval TRUE if an interrupt is processed
3081f11c7f63SJim Harris  *         FALSE if no interrupt was processed
3082f11c7f63SJim Harris  */
3083f11c7f63SJim Harris static
scic_sds_controller_error_vector_interrupt_handler(SCI_CONTROLLER_HANDLE_T controller)3084f11c7f63SJim Harris BOOL scic_sds_controller_error_vector_interrupt_handler(
3085f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller
3086f11c7f63SJim Harris )
3087f11c7f63SJim Harris {
3088f11c7f63SJim Harris    U32 interrupt_status;
3089f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
3090f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
3091f11c7f63SJim Harris 
3092f11c7f63SJim Harris 
3093f11c7f63SJim Harris    interrupt_status = SMU_ISR_READ(this_controller);
3094f11c7f63SJim Harris    interrupt_status &= (SMU_ISR_QUEUE_ERROR | SMU_ISR_QUEUE_SUSPEND);
3095f11c7f63SJim Harris 
3096f11c7f63SJim Harris    if (interrupt_status != 0)
3097f11c7f63SJim Harris    {
3098f11c7f63SJim Harris       // There is an error interrupt pending so let it through and handle
3099f11c7f63SJim Harris       // in the callback
3100f11c7f63SJim Harris       return TRUE;
3101f11c7f63SJim Harris    }
3102f11c7f63SJim Harris 
3103f11c7f63SJim Harris    // There is a race in the hardware that could cause us not to be notified
3104f11c7f63SJim Harris    // of an interrupt completion if we do not take this step.  We will mask
3105f11c7f63SJim Harris    // then unmask the error interrupts so if there was another interrupt
3106f11c7f63SJim Harris    // pending we will be notified.
3107f11c7f63SJim Harris    // Could we write the value of (SMU_ISR_QUEUE_ERROR | SMU_ISR_QUEUE_SUSPEND)?
3108f11c7f63SJim Harris    SMU_IMR_WRITE(this_controller, 0x000000FF);
3109f11c7f63SJim Harris    SMU_IMR_WRITE(this_controller, 0x00000000);
3110f11c7f63SJim Harris 
3111f11c7f63SJim Harris    return FALSE;
3112f11c7f63SJim Harris }
3113f11c7f63SJim Harris 
3114f11c7f63SJim Harris /**
3115f11c7f63SJim Harris  * @brief This is the method provided to handle the error completions when
3116f11c7f63SJim Harris  *        the hardware is using two MSIX messages.
3117f11c7f63SJim Harris  *
3118f11c7f63SJim Harris  * @param[in] controller
3119f11c7f63SJim Harris  */
3120f11c7f63SJim Harris static
scic_sds_controller_error_vector_completion_handler(SCI_CONTROLLER_HANDLE_T controller)3121f11c7f63SJim Harris void scic_sds_controller_error_vector_completion_handler(
3122f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller
3123f11c7f63SJim Harris )
3124f11c7f63SJim Harris {
3125f11c7f63SJim Harris    U32 interrupt_status;
3126f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
3127f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
3128f11c7f63SJim Harris 
3129f11c7f63SJim Harris    SCIC_LOG_TRACE((
3130f11c7f63SJim Harris       sci_base_object_get_logger(controller),
3131f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
3132f11c7f63SJim Harris       "scic_sds_controller_error_vector_completion_handler(0x%d) enter\n",
3133f11c7f63SJim Harris       controller
3134f11c7f63SJim Harris    ));
3135f11c7f63SJim Harris 
3136f11c7f63SJim Harris    interrupt_status = SMU_ISR_READ(this_controller);
3137f11c7f63SJim Harris 
3138f11c7f63SJim Harris    if (
3139f11c7f63SJim Harris             (interrupt_status & SMU_ISR_QUEUE_SUSPEND)
3140f11c7f63SJim Harris          && scic_sds_controller_completion_queue_has_entries(this_controller)
3141f11c7f63SJim Harris       )
3142f11c7f63SJim Harris    {
3143f11c7f63SJim Harris       scic_sds_controller_process_completions(this_controller);
3144f11c7f63SJim Harris 
3145f11c7f63SJim Harris       SMU_ISR_WRITE(this_controller, SMU_ISR_QUEUE_SUSPEND);
3146f11c7f63SJim Harris    }
3147f11c7f63SJim Harris    else
3148f11c7f63SJim Harris    {
3149f11c7f63SJim Harris       SCIC_LOG_ERROR((
3150f11c7f63SJim Harris          sci_base_object_get_logger(this_controller),
3151f11c7f63SJim Harris          SCIC_LOG_OBJECT_CONTROLLER,
3152f11c7f63SJim Harris          "SCIC Controller reports CRC error on completion ISR %x\n",
3153f11c7f63SJim Harris          interrupt_status
3154f11c7f63SJim Harris       ));
3155f11c7f63SJim Harris 
3156f11c7f63SJim Harris       sci_base_state_machine_change_state(
3157f11c7f63SJim Harris          scic_sds_controller_get_base_state_machine(this_controller),
3158f11c7f63SJim Harris          SCI_BASE_CONTROLLER_STATE_FAILED
3159f11c7f63SJim Harris       );
3160f11c7f63SJim Harris 
3161f11c7f63SJim Harris       return;
3162f11c7f63SJim Harris    }
3163f11c7f63SJim Harris 
3164f11c7f63SJim Harris    // If we dont process any completions I am not sure that we want to do this.
3165f11c7f63SJim Harris    // We are in the middle of a hardware fault and should probably be reset.
3166f11c7f63SJim Harris    SMU_IMR_WRITE(this_controller, 0x00000000);
3167f11c7f63SJim Harris }
3168f11c7f63SJim Harris 
3169f11c7f63SJim Harris #endif // !defined(DISABLE_INTERRUPTS)
3170f11c7f63SJim Harris 
3171f11c7f63SJim Harris //****************************************************************************-
3172f11c7f63SJim Harris //* SCIC SDS Controller External Methods
3173f11c7f63SJim Harris //****************************************************************************-
3174f11c7f63SJim Harris 
3175f11c7f63SJim Harris /**
3176f11c7f63SJim Harris  * @brief This method returns the sizeof the SCIC SDS Controller Object
3177f11c7f63SJim Harris  *
3178f11c7f63SJim Harris  * @return U32
3179f11c7f63SJim Harris  */
scic_sds_controller_get_object_size(void)3180f11c7f63SJim Harris U32 scic_sds_controller_get_object_size(void)
3181f11c7f63SJim Harris {
3182f11c7f63SJim Harris    return sizeof(SCIC_SDS_CONTROLLER_T);
3183f11c7f63SJim Harris }
3184f11c7f63SJim Harris 
3185f11c7f63SJim Harris /**
3186f11c7f63SJim Harris  * This method returns the minimum number of timers that are required by the
3187f11c7f63SJim Harris  * controller object.  This will include required timers for phys and ports.
3188f11c7f63SJim Harris  *
3189f11c7f63SJim Harris  * @return U32
3190f11c7f63SJim Harris  * @retval The minimum number of timers that are required to make this
3191f11c7f63SJim Harris  *         controller operational.
3192f11c7f63SJim Harris  */
scic_sds_controller_get_min_timer_count(void)3193f11c7f63SJim Harris U32 scic_sds_controller_get_min_timer_count(void)
3194f11c7f63SJim Harris {
3195f11c7f63SJim Harris    return   SCIC_SDS_CONTROLLER_MIN_TIMER_COUNT
3196f11c7f63SJim Harris           + scic_sds_port_get_min_timer_count()
3197f11c7f63SJim Harris           + scic_sds_phy_get_min_timer_count();
3198f11c7f63SJim Harris }
3199f11c7f63SJim Harris 
3200f11c7f63SJim Harris /**
3201f11c7f63SJim Harris  * This method returns the maximum number of timers that are required by the
3202f11c7f63SJim Harris  * controller object.  This will include required timers for phys and ports.
3203f11c7f63SJim Harris  *
3204f11c7f63SJim Harris  * @return U32
3205f11c7f63SJim Harris  * @retval The maximum number of timers that will be used by the controller
3206f11c7f63SJim Harris  *         object
3207f11c7f63SJim Harris  */
scic_sds_controller_get_max_timer_count(void)3208f11c7f63SJim Harris U32 scic_sds_controller_get_max_timer_count(void)
3209f11c7f63SJim Harris {
3210f11c7f63SJim Harris    return   SCIC_SDS_CONTROLLER_MAX_TIMER_COUNT
3211f11c7f63SJim Harris           + scic_sds_port_get_max_timer_count()
3212f11c7f63SJim Harris           + scic_sds_phy_get_max_timer_count();
3213f11c7f63SJim Harris }
3214f11c7f63SJim Harris 
3215f11c7f63SJim Harris /**
3216f11c7f63SJim Harris  * @brief
3217f11c7f63SJim Harris  *
3218f11c7f63SJim Harris  * @param[in] this_controller
3219f11c7f63SJim Harris  * @param[in] the_port
3220f11c7f63SJim Harris  * @param[in] the_phy
3221f11c7f63SJim Harris  *
3222f11c7f63SJim Harris  * @return none
3223f11c7f63SJim Harris  */
scic_sds_controller_link_up(SCIC_SDS_CONTROLLER_T * this_controller,SCIC_SDS_PORT_T * the_port,SCIC_SDS_PHY_T * the_phy)3224f11c7f63SJim Harris void scic_sds_controller_link_up(
3225f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller,
3226f11c7f63SJim Harris    SCIC_SDS_PORT_T       *the_port,
3227f11c7f63SJim Harris    SCIC_SDS_PHY_T        *the_phy
3228f11c7f63SJim Harris )
3229f11c7f63SJim Harris {
3230f11c7f63SJim Harris    if (this_controller->state_handlers->link_up_handler != NULL)
3231f11c7f63SJim Harris    {
3232f11c7f63SJim Harris       this_controller->state_handlers->link_up_handler(
3233f11c7f63SJim Harris          this_controller, the_port, the_phy);
3234f11c7f63SJim Harris    }
3235f11c7f63SJim Harris    else
3236f11c7f63SJim Harris    {
3237f11c7f63SJim Harris       SCIC_LOG_INFO((
3238f11c7f63SJim Harris          sci_base_object_get_logger(this_controller),
3239f11c7f63SJim Harris          SCIC_LOG_OBJECT_CONTROLLER,
3240f11c7f63SJim Harris          "SCIC Controller linkup event from phy %d in unexpected state %d\n",
3241f11c7f63SJim Harris          the_phy->phy_index,
3242f11c7f63SJim Harris          sci_base_state_machine_get_state(
3243f11c7f63SJim Harris             scic_sds_controller_get_base_state_machine(this_controller))
3244f11c7f63SJim Harris       ));
3245f11c7f63SJim Harris    }
3246f11c7f63SJim Harris }
3247f11c7f63SJim Harris 
3248f11c7f63SJim Harris /**
3249f11c7f63SJim Harris  * @brief
3250f11c7f63SJim Harris  *
3251f11c7f63SJim Harris  * @param[in] this_controller
3252f11c7f63SJim Harris  * @param[in] the_port
3253f11c7f63SJim Harris  * @param[in] the_phy
3254f11c7f63SJim Harris  */
scic_sds_controller_link_down(SCIC_SDS_CONTROLLER_T * this_controller,SCIC_SDS_PORT_T * the_port,SCIC_SDS_PHY_T * the_phy)3255f11c7f63SJim Harris void scic_sds_controller_link_down(
3256f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller,
3257f11c7f63SJim Harris    SCIC_SDS_PORT_T       *the_port,
3258f11c7f63SJim Harris    SCIC_SDS_PHY_T        *the_phy
3259f11c7f63SJim Harris )
3260f11c7f63SJim Harris {
3261f11c7f63SJim Harris    if (this_controller->state_handlers->link_down_handler != NULL)
3262f11c7f63SJim Harris    {
3263f11c7f63SJim Harris       this_controller->state_handlers->link_down_handler(
3264f11c7f63SJim Harris          this_controller, the_port, the_phy);
3265f11c7f63SJim Harris    }
3266f11c7f63SJim Harris    else
3267f11c7f63SJim Harris    {
3268f11c7f63SJim Harris       SCIC_LOG_INFO((
3269f11c7f63SJim Harris          sci_base_object_get_logger(this_controller),
3270f11c7f63SJim Harris          SCIC_LOG_OBJECT_CONTROLLER,
3271f11c7f63SJim Harris          "SCIC Controller linkdown event from phy %d in unexpected state %d\n",
3272f11c7f63SJim Harris          the_phy->phy_index,
3273f11c7f63SJim Harris          sci_base_state_machine_get_state(
3274f11c7f63SJim Harris             scic_sds_controller_get_base_state_machine(this_controller))
3275f11c7f63SJim Harris       ));
3276f11c7f63SJim Harris    }
3277f11c7f63SJim Harris }
3278f11c7f63SJim Harris 
3279f11c7f63SJim Harris /**
3280f11c7f63SJim Harris  * @brief This method is called by the remote device to inform the controller
3281f11c7f63SJim Harris  *        that this remote device has started.
3282f11c7f63SJim Harris  *
3283f11c7f63SJim Harris  * @param[in] this_controller
3284f11c7f63SJim Harris  * @param[in] the_device
3285f11c7f63SJim Harris  */
scic_sds_controller_remote_device_started(SCIC_SDS_CONTROLLER_T * this_controller,SCIC_SDS_REMOTE_DEVICE_T * the_device)3286f11c7f63SJim Harris void scic_sds_controller_remote_device_started(
3287f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T    * this_controller,
3288f11c7f63SJim Harris    SCIC_SDS_REMOTE_DEVICE_T * the_device
3289f11c7f63SJim Harris )
3290f11c7f63SJim Harris {
3291f11c7f63SJim Harris    if (this_controller->state_handlers->remote_device_started_handler != NULL)
3292f11c7f63SJim Harris    {
3293f11c7f63SJim Harris       this_controller->state_handlers->remote_device_started_handler(
3294f11c7f63SJim Harris          this_controller, the_device
3295f11c7f63SJim Harris       );
3296f11c7f63SJim Harris    }
3297f11c7f63SJim Harris    else
3298f11c7f63SJim Harris    {
3299f11c7f63SJim Harris       SCIC_LOG_INFO((
3300f11c7f63SJim Harris          sci_base_object_get_logger(this_controller),
3301f11c7f63SJim Harris          SCIC_LOG_OBJECT_CONTROLLER,
3302f11c7f63SJim Harris          "SCIC Controller 0x%x remote device started event from device 0x%x in unexpected state %d\n",
3303f11c7f63SJim Harris          this_controller,
3304f11c7f63SJim Harris          the_device,
3305f11c7f63SJim Harris          sci_base_state_machine_get_state(
3306f11c7f63SJim Harris             scic_sds_controller_get_base_state_machine(this_controller))
3307f11c7f63SJim Harris       ));
3308f11c7f63SJim Harris    }
3309f11c7f63SJim Harris }
3310f11c7f63SJim Harris 
3311f11c7f63SJim Harris /**
3312f11c7f63SJim Harris  * @brief This is a helper method to determine if any remote devices on this
3313f11c7f63SJim Harris  *        controller are still in the stopping state.
3314f11c7f63SJim Harris  *
3315f11c7f63SJim Harris  * @param[in] this_controller
3316f11c7f63SJim Harris  */
scic_sds_controller_has_remote_devices_stopping(SCIC_SDS_CONTROLLER_T * this_controller)3317f11c7f63SJim Harris BOOL scic_sds_controller_has_remote_devices_stopping(
3318f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T * this_controller
3319f11c7f63SJim Harris )
3320f11c7f63SJim Harris {
3321f11c7f63SJim Harris    U32 index;
3322f11c7f63SJim Harris 
3323f11c7f63SJim Harris    for (index = 0; index < this_controller->remote_node_entries; index++)
3324f11c7f63SJim Harris    {
3325f11c7f63SJim Harris       if (
3326f11c7f63SJim Harris             (this_controller->device_table[index] != NULL)
3327f11c7f63SJim Harris          && (
3328f11c7f63SJim Harris                this_controller->device_table[index]->parent.state_machine.current_state_id
3329f11c7f63SJim Harris             == SCI_BASE_REMOTE_DEVICE_STATE_STOPPING
3330f11c7f63SJim Harris             )
3331f11c7f63SJim Harris          )
3332f11c7f63SJim Harris       {
3333f11c7f63SJim Harris          return TRUE;
3334f11c7f63SJim Harris       }
3335f11c7f63SJim Harris    }
3336f11c7f63SJim Harris 
3337f11c7f63SJim Harris    return FALSE;
3338f11c7f63SJim Harris }
3339f11c7f63SJim Harris 
3340f11c7f63SJim Harris /**
3341f11c7f63SJim Harris  * @brief This method is called by the remote device to inform the controller
3342f11c7f63SJim Harris  *        object that the remote device has stopped.
3343f11c7f63SJim Harris  *
3344f11c7f63SJim Harris  * @param[in] this_controller
3345f11c7f63SJim Harris  * @param[in] the_device
3346f11c7f63SJim Harris  */
scic_sds_controller_remote_device_stopped(SCIC_SDS_CONTROLLER_T * this_controller,SCIC_SDS_REMOTE_DEVICE_T * the_device)3347f11c7f63SJim Harris void scic_sds_controller_remote_device_stopped(
3348f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T    * this_controller,
3349f11c7f63SJim Harris    SCIC_SDS_REMOTE_DEVICE_T * the_device
3350f11c7f63SJim Harris )
3351f11c7f63SJim Harris {
3352f11c7f63SJim Harris    if (this_controller->state_handlers->remote_device_stopped_handler != NULL)
3353f11c7f63SJim Harris    {
3354f11c7f63SJim Harris       this_controller->state_handlers->remote_device_stopped_handler(
3355f11c7f63SJim Harris          this_controller, the_device
3356f11c7f63SJim Harris       );
3357f11c7f63SJim Harris    }
3358f11c7f63SJim Harris    else
3359f11c7f63SJim Harris    {
3360f11c7f63SJim Harris       SCIC_LOG_INFO((
3361f11c7f63SJim Harris          sci_base_object_get_logger(this_controller),
3362f11c7f63SJim Harris          SCIC_LOG_OBJECT_CONTROLLER,
3363f11c7f63SJim Harris          "SCIC Controller 0x%x remote device stopped event from device 0x%x in unexpected state %d\n",
3364f11c7f63SJim Harris          this_controller,
3365f11c7f63SJim Harris          the_device,
3366f11c7f63SJim Harris          sci_base_state_machine_get_state(
3367f11c7f63SJim Harris             scic_sds_controller_get_base_state_machine(this_controller))
3368f11c7f63SJim Harris       ));
3369f11c7f63SJim Harris    }
3370f11c7f63SJim Harris }
3371f11c7f63SJim Harris 
3372f11c7f63SJim Harris /**
3373f11c7f63SJim Harris  * @brief This method will write to the SCU PCP register the request value.
3374f11c7f63SJim Harris  *        The method is used to suspend/resume ports, devices, and phys.
3375f11c7f63SJim Harris  *
3376f11c7f63SJim Harris  * @param[in] this_controller
3377f11c7f63SJim Harris  * @param[in] request
3378f11c7f63SJim Harris  */
scic_sds_controller_post_request(SCIC_SDS_CONTROLLER_T * this_controller,U32 request)3379f11c7f63SJim Harris void scic_sds_controller_post_request(
3380f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller,
3381f11c7f63SJim Harris    U32                    request
3382f11c7f63SJim Harris )
3383f11c7f63SJim Harris {
3384f11c7f63SJim Harris    SCIC_LOG_INFO((
3385f11c7f63SJim Harris       sci_base_object_get_logger(this_controller),
3386f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER | SCIC_LOG_OBJECT_COMPLETION_QUEUE,
3387f11c7f63SJim Harris       "SCIC Controller 0x%08x post request 0x%08x\n",
3388f11c7f63SJim Harris       this_controller, request
3389f11c7f63SJim Harris    ));
3390f11c7f63SJim Harris 
3391f11c7f63SJim Harris    SMU_PCP_WRITE(this_controller, request);
3392f11c7f63SJim Harris }
3393f11c7f63SJim Harris 
3394f11c7f63SJim Harris /**
3395f11c7f63SJim Harris  * @brief This method will copy the soft copy of the task context into
3396f11c7f63SJim Harris  *        the physical memory accessible by the controller.
3397f11c7f63SJim Harris  *
3398f11c7f63SJim Harris  * @note After this call is made the SCIC_SDS_IO_REQUEST object will
3399f11c7f63SJim Harris  *       always point to the physical memory version of the task context.
3400f11c7f63SJim Harris  *       Thus, all subsequent updates to the task context are performed in
3401f11c7f63SJim Harris  *       the TC table (i.e. DMAable memory).
3402f11c7f63SJim Harris  *
3403f11c7f63SJim Harris  * @param[in]  this_controller This parameter specifies the controller for
3404f11c7f63SJim Harris  *             which to copy the task context.
3405f11c7f63SJim Harris  * @param[in]  this_request This parameter specifies the request for which
3406f11c7f63SJim Harris  *             the task context is being copied.
3407f11c7f63SJim Harris  *
3408f11c7f63SJim Harris  * @return none
3409f11c7f63SJim Harris  */
scic_sds_controller_copy_task_context(SCIC_SDS_CONTROLLER_T * this_controller,SCIC_SDS_REQUEST_T * this_request)3410f11c7f63SJim Harris void scic_sds_controller_copy_task_context(
3411f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller,
3412f11c7f63SJim Harris    SCIC_SDS_REQUEST_T    *this_request
3413f11c7f63SJim Harris )
3414f11c7f63SJim Harris {
3415f11c7f63SJim Harris    SCU_TASK_CONTEXT_T *task_context_buffer;
3416f11c7f63SJim Harris 
3417f11c7f63SJim Harris    task_context_buffer = scic_sds_controller_get_task_context_buffer(
3418f11c7f63SJim Harris                             this_controller, this_request->io_tag
3419f11c7f63SJim Harris                          );
3420f11c7f63SJim Harris 
3421f11c7f63SJim Harris    memcpy(
3422f11c7f63SJim Harris       task_context_buffer,
3423f11c7f63SJim Harris       this_request->task_context_buffer,
3424f11c7f63SJim Harris       SCI_FIELD_OFFSET(SCU_TASK_CONTEXT_T, sgl_snapshot_ac)
3425f11c7f63SJim Harris    );
3426f11c7f63SJim Harris 
3427f11c7f63SJim Harris    // Now that the soft copy of the TC has been copied into the TC
3428f11c7f63SJim Harris    // table accessible by the silicon.  Thus, any further changes to
3429f11c7f63SJim Harris    // the TC (e.g. TC termination) occur in the appropriate location.
3430f11c7f63SJim Harris    this_request->task_context_buffer = task_context_buffer;
3431f11c7f63SJim Harris }
3432f11c7f63SJim Harris 
3433f11c7f63SJim Harris /**
3434f11c7f63SJim Harris  * @brief This method returns the task context buffer for the given io tag.
3435f11c7f63SJim Harris  *
3436f11c7f63SJim Harris  * @param[in] this_controller
3437f11c7f63SJim Harris  * @param[in] io_tag
3438f11c7f63SJim Harris  *
3439f11c7f63SJim Harris  * @return struct SCU_TASK_CONTEXT*
3440f11c7f63SJim Harris  */
scic_sds_controller_get_task_context_buffer(SCIC_SDS_CONTROLLER_T * this_controller,U16 io_tag)3441f11c7f63SJim Harris SCU_TASK_CONTEXT_T * scic_sds_controller_get_task_context_buffer(
3442f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T * this_controller,
3443f11c7f63SJim Harris    U16                     io_tag
3444f11c7f63SJim Harris )
3445f11c7f63SJim Harris {
3446f11c7f63SJim Harris    U16 task_index = scic_sds_io_tag_get_index(io_tag);
3447f11c7f63SJim Harris 
3448f11c7f63SJim Harris    if (task_index < this_controller->task_context_entries)
3449f11c7f63SJim Harris    {
3450f11c7f63SJim Harris       return &this_controller->task_context_table[task_index];
3451f11c7f63SJim Harris    }
3452f11c7f63SJim Harris 
3453f11c7f63SJim Harris    return NULL;
3454f11c7f63SJim Harris }
3455f11c7f63SJim Harris 
3456f11c7f63SJim Harris /**
3457f11c7f63SJim Harris  * @brief This method returnst the sequence value from the io tag value
3458f11c7f63SJim Harris  *
3459f11c7f63SJim Harris  * @param[in] this_controller
3460f11c7f63SJim Harris  * @param[in] io_tag
3461f11c7f63SJim Harris  *
3462f11c7f63SJim Harris  * @return U16
3463f11c7f63SJim Harris  */
scic_sds_controller_get_io_sequence_from_tag(SCIC_SDS_CONTROLLER_T * this_controller,U16 io_tag)3464f11c7f63SJim Harris U16 scic_sds_controller_get_io_sequence_from_tag(
3465f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller,
3466f11c7f63SJim Harris    U16                    io_tag
3467f11c7f63SJim Harris )
3468f11c7f63SJim Harris {
3469f11c7f63SJim Harris    return scic_sds_io_tag_get_sequence(io_tag);
3470f11c7f63SJim Harris }
3471f11c7f63SJim Harris 
3472f11c7f63SJim Harris /**
3473f11c7f63SJim Harris  * @brief This method returns the IO request associated with the tag value
3474f11c7f63SJim Harris  *
3475f11c7f63SJim Harris  * @param[in] this_controller
3476f11c7f63SJim Harris  * @param[in] io_tag
3477f11c7f63SJim Harris  *
3478f11c7f63SJim Harris  * @return SCIC_SDS_IO_REQUEST_T*
3479f11c7f63SJim Harris  * @retval NULL if there is no valid IO request at the tag value
3480f11c7f63SJim Harris  */
scic_sds_controller_get_io_request_from_tag(SCIC_SDS_CONTROLLER_T * this_controller,U16 io_tag)3481f11c7f63SJim Harris SCIC_SDS_REQUEST_T *scic_sds_controller_get_io_request_from_tag(
3482f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller,
3483f11c7f63SJim Harris    U16                    io_tag
3484f11c7f63SJim Harris )
3485f11c7f63SJim Harris {
3486f11c7f63SJim Harris    U16 task_index;
3487f11c7f63SJim Harris    U16 task_sequence;
3488f11c7f63SJim Harris 
3489f11c7f63SJim Harris    task_index = scic_sds_io_tag_get_index(io_tag);
3490f11c7f63SJim Harris 
3491f11c7f63SJim Harris    if (task_index  < this_controller->task_context_entries)
3492f11c7f63SJim Harris    {
3493f11c7f63SJim Harris       if (this_controller->io_request_table[task_index] != SCI_INVALID_HANDLE)
3494f11c7f63SJim Harris       {
3495f11c7f63SJim Harris          task_sequence = scic_sds_io_tag_get_sequence(io_tag);
3496f11c7f63SJim Harris 
3497f11c7f63SJim Harris          if (task_sequence == this_controller->io_request_sequence[task_index])
3498f11c7f63SJim Harris          {
3499f11c7f63SJim Harris             return this_controller->io_request_table[task_index];
3500f11c7f63SJim Harris          }
3501f11c7f63SJim Harris       }
3502f11c7f63SJim Harris    }
3503f11c7f63SJim Harris 
3504f11c7f63SJim Harris    return SCI_INVALID_HANDLE;
3505f11c7f63SJim Harris }
3506f11c7f63SJim Harris 
3507f11c7f63SJim Harris /**
3508f11c7f63SJim Harris  * @brief This method allocates remote node index and the reserves the
3509f11c7f63SJim Harris  *        remote node context space for use. This method can fail if there
3510f11c7f63SJim Harris  *        are no more remote node index available.
3511f11c7f63SJim Harris  *
3512f11c7f63SJim Harris  * @param[in] this_controller This is the controller object which contains
3513f11c7f63SJim Harris  *            the set of free remote node ids
3514f11c7f63SJim Harris  * @param[in] the_devce This is the device object which is requesting the a
3515f11c7f63SJim Harris  *            remote node id
3516*816d5c1eSGordon Bergling  * @param[out] node_id This is the remote node id that is assigned to the
3517f11c7f63SJim Harris  *             device if one is available
3518f11c7f63SJim Harris  *
3519f11c7f63SJim Harris  * @return SCI_STATUS
3520f11c7f63SJim Harris  * @retval SCI_FAILURE_OUT_OF_RESOURCES if there are no available remote
3521f11c7f63SJim Harris  *         node index available.
3522f11c7f63SJim Harris  */
scic_sds_controller_allocate_remote_node_context(SCIC_SDS_CONTROLLER_T * this_controller,SCIC_SDS_REMOTE_DEVICE_T * the_device,U16 * node_id)3523f11c7f63SJim Harris SCI_STATUS scic_sds_controller_allocate_remote_node_context(
3524f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T    * this_controller,
3525f11c7f63SJim Harris    SCIC_SDS_REMOTE_DEVICE_T * the_device,
3526f11c7f63SJim Harris    U16                      * node_id
3527f11c7f63SJim Harris )
3528f11c7f63SJim Harris {
3529f11c7f63SJim Harris    U16 node_index;
3530f11c7f63SJim Harris    U32 remote_node_count = scic_sds_remote_device_node_count(the_device);
3531f11c7f63SJim Harris 
3532f11c7f63SJim Harris    node_index = scic_sds_remote_node_table_allocate_remote_node(
3533f11c7f63SJim Harris                   &this_controller->available_remote_nodes, remote_node_count
3534f11c7f63SJim Harris               );
3535f11c7f63SJim Harris 
3536f11c7f63SJim Harris    if (node_index != SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX)
3537f11c7f63SJim Harris    {
3538f11c7f63SJim Harris       this_controller->device_table[node_index] = the_device;
3539f11c7f63SJim Harris 
3540f11c7f63SJim Harris       *node_id = node_index;
3541f11c7f63SJim Harris 
3542f11c7f63SJim Harris       return SCI_SUCCESS;
3543f11c7f63SJim Harris    }
3544f11c7f63SJim Harris 
3545f11c7f63SJim Harris    return SCI_FAILURE_INSUFFICIENT_RESOURCES;
3546f11c7f63SJim Harris }
3547f11c7f63SJim Harris 
3548f11c7f63SJim Harris /**
3549f11c7f63SJim Harris  * @brief This method frees the remote node index back to the available
3550f11c7f63SJim Harris  *        pool.  Once this is done the remote node context buffer is no
3551f11c7f63SJim Harris  *        longer valid and can not be used.
3552f11c7f63SJim Harris  *
3553f11c7f63SJim Harris  * @param[in] this_controller
3554f11c7f63SJim Harris  * @param[in] the_device
3555f11c7f63SJim Harris  * @param[in] node_id
3556f11c7f63SJim Harris  *
3557f11c7f63SJim Harris  * @return none
3558f11c7f63SJim Harris  */
scic_sds_controller_free_remote_node_context(SCIC_SDS_CONTROLLER_T * this_controller,SCIC_SDS_REMOTE_DEVICE_T * the_device,U16 node_id)3559f11c7f63SJim Harris void scic_sds_controller_free_remote_node_context(
3560f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T    * this_controller,
3561f11c7f63SJim Harris    SCIC_SDS_REMOTE_DEVICE_T * the_device,
3562f11c7f63SJim Harris    U16                        node_id
3563f11c7f63SJim Harris )
3564f11c7f63SJim Harris {
3565f11c7f63SJim Harris    U32 remote_node_count = scic_sds_remote_device_node_count(the_device);
3566f11c7f63SJim Harris 
3567f11c7f63SJim Harris    if (this_controller->device_table[node_id] == the_device)
3568f11c7f63SJim Harris    {
3569f11c7f63SJim Harris       this_controller->device_table[node_id] = SCI_INVALID_HANDLE;
3570f11c7f63SJim Harris 
3571f11c7f63SJim Harris       scic_sds_remote_node_table_release_remote_node_index(
3572f11c7f63SJim Harris          &this_controller->available_remote_nodes, remote_node_count, node_id
3573f11c7f63SJim Harris       );
3574f11c7f63SJim Harris    }
3575f11c7f63SJim Harris }
3576f11c7f63SJim Harris 
3577f11c7f63SJim Harris /**
3578f11c7f63SJim Harris  * @brief This method returns the SCU_REMOTE_NODE_CONTEXT for the specified
3579f11c7f63SJim Harris  *        remote node id.
3580f11c7f63SJim Harris  *
3581f11c7f63SJim Harris  * @param[in] this_controller
3582f11c7f63SJim Harris  * @param[in] node_id
3583f11c7f63SJim Harris  *
3584f11c7f63SJim Harris  * @return SCU_REMOTE_NODE_CONTEXT_T*
3585f11c7f63SJim Harris  */
scic_sds_controller_get_remote_node_context_buffer(SCIC_SDS_CONTROLLER_T * this_controller,U16 node_id)3586f11c7f63SJim Harris SCU_REMOTE_NODE_CONTEXT_T *scic_sds_controller_get_remote_node_context_buffer(
3587f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller,
3588f11c7f63SJim Harris    U16                    node_id
3589f11c7f63SJim Harris )
3590f11c7f63SJim Harris {
3591f11c7f63SJim Harris    if (
3592f11c7f63SJim Harris            (node_id < this_controller->remote_node_entries)
3593f11c7f63SJim Harris         && (this_controller->device_table[node_id] != SCI_INVALID_HANDLE)
3594f11c7f63SJim Harris       )
3595f11c7f63SJim Harris    {
3596f11c7f63SJim Harris       return &this_controller->remote_node_context_table[node_id];
3597f11c7f63SJim Harris    }
3598f11c7f63SJim Harris 
3599f11c7f63SJim Harris    return NULL;
3600f11c7f63SJim Harris }
3601f11c7f63SJim Harris 
3602f11c7f63SJim Harris /**
3603f11c7f63SJim Harris  * This method will combind the frame header and frame buffer to create
3604f11c7f63SJim Harris  * a SATA D2H register FIS
3605f11c7f63SJim Harris  *
3606f11c7f63SJim Harris  * @param[out] resposne_buffer This is the buffer into which the D2H register
3607f11c7f63SJim Harris  *             FIS will be constructed.
3608f11c7f63SJim Harris  * @param[in]  frame_header This is the frame header returned by the hardware.
3609f11c7f63SJim Harris  * @param[in]  frame_buffer This is the frame buffer returned by the hardware.
3610f11c7f63SJim Harris  *
3611f11c7f63SJim Harris  * @erturn none
3612f11c7f63SJim Harris  */
scic_sds_controller_copy_sata_response(void * response_buffer,void * frame_header,void * frame_buffer)3613f11c7f63SJim Harris void scic_sds_controller_copy_sata_response(
3614f11c7f63SJim Harris    void * response_buffer,
3615f11c7f63SJim Harris    void * frame_header,
3616f11c7f63SJim Harris    void * frame_buffer
3617f11c7f63SJim Harris )
3618f11c7f63SJim Harris {
3619f11c7f63SJim Harris    memcpy(
3620f11c7f63SJim Harris       response_buffer,
3621f11c7f63SJim Harris       frame_header,
3622f11c7f63SJim Harris       sizeof(U32)
3623f11c7f63SJim Harris    );
3624f11c7f63SJim Harris 
3625f11c7f63SJim Harris    memcpy(
3626f11c7f63SJim Harris       (char *)((char *)response_buffer + sizeof(U32)),
3627f11c7f63SJim Harris       frame_buffer,
3628f11c7f63SJim Harris       sizeof(SATA_FIS_REG_D2H_T) - sizeof(U32)
3629f11c7f63SJim Harris    );
3630f11c7f63SJim Harris }
3631f11c7f63SJim Harris 
3632f11c7f63SJim Harris /**
3633f11c7f63SJim Harris  * @brief This method releases the frame once this is done the frame is
3634f11c7f63SJim Harris  *        available for re-use by the hardware.  The data contained in the
3635f11c7f63SJim Harris  *        frame header and frame buffer is no longer valid.
3636f11c7f63SJim Harris  *        The UF queue get pointer is only updated if UF control indicates
3637f11c7f63SJim Harris  *        this is appropriate.
3638f11c7f63SJim Harris  *
3639f11c7f63SJim Harris  * @param[in] this_controller
3640f11c7f63SJim Harris  * @param[in] frame_index
3641f11c7f63SJim Harris  *
3642f11c7f63SJim Harris  * @return none
3643f11c7f63SJim Harris  */
scic_sds_controller_release_frame(SCIC_SDS_CONTROLLER_T * this_controller,U32 frame_index)3644f11c7f63SJim Harris void scic_sds_controller_release_frame(
3645f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller,
3646f11c7f63SJim Harris    U32                    frame_index
3647f11c7f63SJim Harris )
3648f11c7f63SJim Harris {
3649f11c7f63SJim Harris    if (scic_sds_unsolicited_frame_control_release_frame(
3650f11c7f63SJim Harris           &this_controller->uf_control, frame_index) == TRUE)
3651f11c7f63SJim Harris       SCU_UFQGP_WRITE(this_controller, this_controller->uf_control.get);
3652f11c7f63SJim Harris }
3653f11c7f63SJim Harris 
3654f11c7f63SJim Harris #ifdef SCI_LOGGING
scic_sds_controller_initialize_state_logging(SCIC_SDS_CONTROLLER_T * this_controller)3655f11c7f63SJim Harris void scic_sds_controller_initialize_state_logging(
3656f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
3657f11c7f63SJim Harris )
3658f11c7f63SJim Harris {
3659f11c7f63SJim Harris    sci_base_state_machine_logger_initialize(
3660f11c7f63SJim Harris       &this_controller->parent.state_machine_logger,
3661f11c7f63SJim Harris       &this_controller->parent.state_machine,
3662f11c7f63SJim Harris       &this_controller->parent.parent,
3663f11c7f63SJim Harris       scic_cb_logger_log_states,
3664f11c7f63SJim Harris       "SCIC_SDS_CONTROLLER_T", "base state machine",
3665f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER
3666f11c7f63SJim Harris    );
3667f11c7f63SJim Harris }
3668f11c7f63SJim Harris 
scic_sds_controller_deinitialize_state_logging(SCIC_SDS_CONTROLLER_T * this_controller)3669f11c7f63SJim Harris void scic_sds_controller_deinitialize_state_logging(
3670f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
3671f11c7f63SJim Harris )
3672f11c7f63SJim Harris {
3673f11c7f63SJim Harris    sci_base_state_machine_logger_deinitialize(
3674f11c7f63SJim Harris       &this_controller->parent.state_machine_logger,
3675f11c7f63SJim Harris       &this_controller->parent.state_machine
3676f11c7f63SJim Harris    );
3677f11c7f63SJim Harris }
3678f11c7f63SJim Harris #endif
3679f11c7f63SJim Harris 
3680f11c7f63SJim Harris /**
3681f11c7f63SJim Harris  * @brief This method sets user parameters and OEM parameters to
3682f11c7f63SJim Harris  *        default values.  Users can override these values utilizing
3683f11c7f63SJim Harris  *        the scic_user_parameters_set() and scic_oem_parameters_set()
3684f11c7f63SJim Harris  *        methods.
3685f11c7f63SJim Harris  *
3686f11c7f63SJim Harris  * @param[in] controller This parameter specifies the controller for
3687f11c7f63SJim Harris  *            which to set the configuration parameters to their
3688f11c7f63SJim Harris  *            default values.
3689f11c7f63SJim Harris  *
3690f11c7f63SJim Harris  * @return none
3691f11c7f63SJim Harris  */
3692f11c7f63SJim Harris static
scic_sds_controller_set_default_config_parameters(SCIC_SDS_CONTROLLER_T * this_controller)3693f11c7f63SJim Harris void scic_sds_controller_set_default_config_parameters(
3694f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller
3695f11c7f63SJim Harris )
3696f11c7f63SJim Harris {
3697f11c7f63SJim Harris    U16 index;
3698f11c7f63SJim Harris 
3699f11c7f63SJim Harris    // Default to APC mode.
3700f11c7f63SJim Harris    this_controller->oem_parameters.sds1.controller.mode_type = SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE;
3701f11c7f63SJim Harris 
3702f11c7f63SJim Harris    // Default to 1
3703f11c7f63SJim Harris    this_controller->oem_parameters.sds1.controller.max_number_concurrent_device_spin_up = 1;
3704f11c7f63SJim Harris 
3705f11c7f63SJim Harris    // Default to no SSC operation.
3706f11c7f63SJim Harris    this_controller->oem_parameters.sds1.controller.ssc_sata_tx_spread_level = 0;
3707f11c7f63SJim Harris    this_controller->oem_parameters.sds1.controller.ssc_sas_tx_spread_level  = 0;
3708f11c7f63SJim Harris    this_controller->oem_parameters.sds1.controller.ssc_sas_tx_type          = 0;
3709f11c7f63SJim Harris 
3710f11c7f63SJim Harris    // Default to all phys to using short cables
3711f11c7f63SJim Harris    this_controller->oem_parameters.sds1.controller.cable_selection_mask = 0;
3712f11c7f63SJim Harris 
3713f11c7f63SJim Harris    // Initialize all of the port parameter information to narrow ports.
3714f11c7f63SJim Harris    for (index = 0; index < SCI_MAX_PORTS; index++)
3715f11c7f63SJim Harris    {
3716f11c7f63SJim Harris       this_controller->oem_parameters.sds1.ports[index].phy_mask = 0;
3717f11c7f63SJim Harris    }
3718f11c7f63SJim Harris 
3719f11c7f63SJim Harris    // Initialize all of the phy parameter information.
3720f11c7f63SJim Harris    for (index = 0; index < SCI_MAX_PHYS; index++)
3721f11c7f63SJim Harris    {
3722f11c7f63SJim Harris       // Default to 6G (i.e. Gen 3) for now.  User can override if
3723f11c7f63SJim Harris       // they choose.
3724f11c7f63SJim Harris       this_controller->user_parameters.sds1.phys[index].max_speed_generation = 2;
3725f11c7f63SJim Harris 
3726f11c7f63SJim Harris       //the frequencies cannot be 0
3727f11c7f63SJim Harris       this_controller->user_parameters.sds1.phys[index].align_insertion_frequency = 0x7f;
3728f11c7f63SJim Harris       this_controller->user_parameters.sds1.phys[index].in_connection_align_insertion_frequency = 0xff;
3729f11c7f63SJim Harris       this_controller->user_parameters.sds1.phys[index].notify_enable_spin_up_insertion_frequency = 0x33;
3730f11c7f63SJim Harris 
3731f11c7f63SJim Harris       // Previous Vitesse based expanders had a arbitration issue that
3732f11c7f63SJim Harris       // is worked around by having the upper 32-bits of SAS address
3733f11c7f63SJim Harris       // with a value greater then the Vitesse company identifier.
3734f11c7f63SJim Harris       // Hence, usage of 0x5FCFFFFF.
3735f11c7f63SJim Harris       this_controller->oem_parameters.sds1.phys[index].sas_address.sci_format.high
3736f11c7f63SJim Harris          = 0x5FCFFFFF;
3737f11c7f63SJim Harris 
3738f11c7f63SJim Harris       // Add in controller index to ensure each controller will have unique SAS addresses by default.
3739f11c7f63SJim Harris       this_controller->oem_parameters.sds1.phys[index].sas_address.sci_format.low
3740f11c7f63SJim Harris          = 0x00000001 + this_controller->controller_index;
3741f11c7f63SJim Harris 
3742f11c7f63SJim Harris       if (  (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A0)
3743f11c7f63SJim Harris          || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_A2)
3744f11c7f63SJim Harris          || (this_controller->pci_revision == SCIC_SDS_PCI_REVISION_B0) )
3745f11c7f63SJim Harris       {
3746f11c7f63SJim Harris          this_controller->oem_parameters.sds1.phys[index].afe_tx_amp_control0 = 0x000E7C03;
3747f11c7f63SJim Harris          this_controller->oem_parameters.sds1.phys[index].afe_tx_amp_control1 = 0x000E7C03;
3748f11c7f63SJim Harris          this_controller->oem_parameters.sds1.phys[index].afe_tx_amp_control2 = 0x000E7C03;
3749f11c7f63SJim Harris          this_controller->oem_parameters.sds1.phys[index].afe_tx_amp_control3 = 0x000E7C03;
3750f11c7f63SJim Harris       }
3751f11c7f63SJim Harris       else // This must be SCIC_SDS_PCI_REVISION_C0
3752f11c7f63SJim Harris       {
3753f11c7f63SJim Harris          this_controller->oem_parameters.sds1.phys[index].afe_tx_amp_control0 = 0x000BDD08;
3754f11c7f63SJim Harris          this_controller->oem_parameters.sds1.phys[index].afe_tx_amp_control1 = 0x000B7069;
3755f11c7f63SJim Harris          this_controller->oem_parameters.sds1.phys[index].afe_tx_amp_control2 = 0x000B7C09;
3756f11c7f63SJim Harris          this_controller->oem_parameters.sds1.phys[index].afe_tx_amp_control3 = 0x000AFC6E;
3757f11c7f63SJim Harris       }
3758f11c7f63SJim Harris    }
3759f11c7f63SJim Harris 
3760f11c7f63SJim Harris    this_controller->user_parameters.sds1.stp_inactivity_timeout = 5;
3761f11c7f63SJim Harris    this_controller->user_parameters.sds1.ssp_inactivity_timeout = 5;
3762f11c7f63SJim Harris    this_controller->user_parameters.sds1.stp_max_occupancy_timeout = 5;
3763f11c7f63SJim Harris    this_controller->user_parameters.sds1.ssp_max_occupancy_timeout = 20;
3764f11c7f63SJim Harris    this_controller->user_parameters.sds1.no_outbound_task_timeout = 20;
3765f11c7f63SJim Harris 
3766f11c7f63SJim Harris }
3767f11c7f63SJim Harris 
3768f11c7f63SJim Harris 
3769f11c7f63SJim Harris /**
3770f11c7f63SJim Harris  * @brief This method release resources in SCI controller.
3771f11c7f63SJim Harris  *
3772f11c7f63SJim Harris  * @param[in] this_controller This parameter specifies the core
3773f11c7f63SJim Harris  *            controller and associated objects whose resources are to be
3774f11c7f63SJim Harris  *            released.
3775f11c7f63SJim Harris  *
3776f11c7f63SJim Harris  * @return This method returns a value indicating if the operation succeeded.
3777f11c7f63SJim Harris  * @retval SCI_SUCCESS This value indicates that all the timers are destroyed.
3778f11c7f63SJim Harris  * @retval SCI_FAILURE This value indicates certain failure during the process
3779f11c7f63SJim Harris  *            of cleaning timer resource.
3780f11c7f63SJim Harris  */
3781f11c7f63SJim Harris static
scic_sds_controller_release_resource(SCIC_SDS_CONTROLLER_T * this_controller)3782f11c7f63SJim Harris SCI_STATUS scic_sds_controller_release_resource(
3783f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T * this_controller
3784f11c7f63SJim Harris )
3785f11c7f63SJim Harris {
3786f11c7f63SJim Harris    SCIC_SDS_PORT_T * port;
3787f11c7f63SJim Harris    SCIC_SDS_PHY_T * phy;
3788f11c7f63SJim Harris    U8 index;
3789f11c7f63SJim Harris 
3790f11c7f63SJim Harris    SCIC_LOG_TRACE((
3791f11c7f63SJim Harris       sci_base_object_get_logger(this_controller),
3792f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER | SCIC_LOG_OBJECT_INITIALIZATION,
3793f11c7f63SJim Harris       "scic_sds_controller_release_resource(0x%x) enter\n",
3794f11c7f63SJim Harris       this_controller
3795f11c7f63SJim Harris    ));
3796f11c7f63SJim Harris 
3797f11c7f63SJim Harris    if(this_controller->phy_startup_timer != NULL)
3798f11c7f63SJim Harris    {
3799f11c7f63SJim Harris       scic_cb_timer_destroy(this_controller, this_controller->phy_startup_timer);
3800f11c7f63SJim Harris       this_controller->phy_startup_timer = NULL;
3801f11c7f63SJim Harris    }
3802f11c7f63SJim Harris 
3803f11c7f63SJim Harris    if(this_controller->power_control.timer != NULL)
3804f11c7f63SJim Harris    {
3805f11c7f63SJim Harris       scic_cb_timer_destroy(this_controller, this_controller->power_control.timer);
3806f11c7f63SJim Harris       this_controller->power_control.timer = NULL;
3807f11c7f63SJim Harris    }
3808f11c7f63SJim Harris 
3809f11c7f63SJim Harris    if(this_controller->timeout_timer != NULL)
3810f11c7f63SJim Harris    {
3811f11c7f63SJim Harris       scic_cb_timer_destroy(this_controller, this_controller->timeout_timer);
3812f11c7f63SJim Harris       this_controller->timeout_timer = NULL;
3813f11c7f63SJim Harris    }
3814f11c7f63SJim Harris 
3815f11c7f63SJim Harris    scic_sds_port_configuration_agent_release_resource(
3816f11c7f63SJim Harris       this_controller,
3817f11c7f63SJim Harris       &this_controller->port_agent);
3818f11c7f63SJim Harris 
3819f11c7f63SJim Harris    for(index = 0; index < SCI_MAX_PORTS+1; index++)
3820f11c7f63SJim Harris    {
3821f11c7f63SJim Harris       port = &this_controller->port_table[index];
3822f11c7f63SJim Harris       scic_sds_port_release_resource(this_controller, port);
3823f11c7f63SJim Harris    }
3824f11c7f63SJim Harris 
3825f11c7f63SJim Harris    for(index = 0; index < SCI_MAX_PHYS; index++)
3826f11c7f63SJim Harris    {
3827f11c7f63SJim Harris       phy = &this_controller->phy_table[index];
3828f11c7f63SJim Harris       scic_sds_phy_release_resource(this_controller, phy);
3829f11c7f63SJim Harris    }
3830f11c7f63SJim Harris 
3831f11c7f63SJim Harris    return SCI_SUCCESS;
3832f11c7f63SJim Harris }
3833f11c7f63SJim Harris 
3834f11c7f63SJim Harris 
3835f11c7f63SJim Harris /**
3836f11c7f63SJim Harris  * @brief This method process the ports configured message from port configuration
3837f11c7f63SJim Harris  *           agent.
3838f11c7f63SJim Harris  *
3839f11c7f63SJim Harris  * @param[in] this_controller This parameter specifies the core
3840f11c7f63SJim Harris  *            controller that its ports are configured.
3841f11c7f63SJim Harris  *
3842f11c7f63SJim Harris  * @return None.
3843f11c7f63SJim Harris  */
scic_sds_controller_port_agent_configured_ports(SCIC_SDS_CONTROLLER_T * this_controller)3844f11c7f63SJim Harris void scic_sds_controller_port_agent_configured_ports(
3845f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T * this_controller
3846f11c7f63SJim Harris )
3847f11c7f63SJim Harris {
3848f11c7f63SJim Harris    //simply transit to ready. The function below checks the controller state
3849f11c7f63SJim Harris    scic_sds_controller_transition_to_ready(
3850f11c7f63SJim Harris       this_controller, SCI_SUCCESS
3851f11c7f63SJim Harris    );
3852f11c7f63SJim Harris }
3853f11c7f63SJim Harris 
3854f11c7f63SJim Harris 
3855f11c7f63SJim Harris //****************************************************************************-
3856f11c7f63SJim Harris //* SCIC Controller Public Methods
3857f11c7f63SJim Harris //****************************************************************************-
3858f11c7f63SJim Harris 
scic_controller_construct(SCI_LIBRARY_HANDLE_T library,SCI_CONTROLLER_HANDLE_T controller,void * user_object)3859f11c7f63SJim Harris SCI_STATUS scic_controller_construct(
3860f11c7f63SJim Harris    SCI_LIBRARY_HANDLE_T    library,
3861f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller,
3862f11c7f63SJim Harris    void *                  user_object
3863f11c7f63SJim Harris )
3864f11c7f63SJim Harris {
3865f11c7f63SJim Harris    SCIC_SDS_LIBRARY_T    *my_library;
3866f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
3867f11c7f63SJim Harris 
3868f11c7f63SJim Harris    my_library = (SCIC_SDS_LIBRARY_T *)library;
3869f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
3870f11c7f63SJim Harris 
3871f11c7f63SJim Harris    SCIC_LOG_TRACE((
3872f11c7f63SJim Harris       sci_base_object_get_logger(library),
3873f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER | SCIC_LOG_OBJECT_INITIALIZATION,
3874f11c7f63SJim Harris       "scic_controller_construct(0x%x, 0x%x) enter\n",
3875f11c7f63SJim Harris       library, controller
3876f11c7f63SJim Harris    ));
3877f11c7f63SJim Harris 
3878f11c7f63SJim Harris    // Just clear out the memory of the structure to be safe.
3879f11c7f63SJim Harris    memset(this_controller, 0, sizeof(SCIC_SDS_CONTROLLER_T));
3880f11c7f63SJim Harris 
3881f11c7f63SJim Harris    // Make sure that the static data is assigned before moving onto the
3882f11c7f63SJim Harris    // base constroller construct as this will cause the controller to
3883f11c7f63SJim Harris    // enter its initial state and the controller_index and pci_revision
3884f11c7f63SJim Harris    // will be required to complete those operations correctly
3885f11c7f63SJim Harris    this_controller->controller_index =
3886f11c7f63SJim Harris       scic_sds_library_get_controller_index(my_library, this_controller);
3887f11c7f63SJim Harris 
3888f11c7f63SJim Harris    this_controller->pci_revision = my_library->pci_revision;
3889f11c7f63SJim Harris 
3890f11c7f63SJim Harris    sci_base_controller_construct(
3891f11c7f63SJim Harris       &this_controller->parent,
3892f11c7f63SJim Harris       sci_base_object_get_logger(my_library),
3893f11c7f63SJim Harris       scic_sds_controller_state_table,
3894f11c7f63SJim Harris       this_controller->memory_descriptors,
3895f11c7f63SJim Harris       ARRAY_SIZE(this_controller->memory_descriptors),
3896f11c7f63SJim Harris       NULL
3897f11c7f63SJim Harris    );
3898f11c7f63SJim Harris 
3899f11c7f63SJim Harris    sci_object_set_association(controller, user_object);
3900f11c7f63SJim Harris 
3901f11c7f63SJim Harris    scic_sds_controller_initialize_state_logging(this_controller);
3902f11c7f63SJim Harris 
3903f11c7f63SJim Harris    scic_sds_pci_bar_initialization(this_controller);
3904f11c7f63SJim Harris 
3905f11c7f63SJim Harris    return SCI_SUCCESS;
3906f11c7f63SJim Harris }
3907f11c7f63SJim Harris 
3908f11c7f63SJim Harris // ---------------------------------------------------------------------------
3909f11c7f63SJim Harris 
scic_controller_initialize(SCI_CONTROLLER_HANDLE_T controller)3910f11c7f63SJim Harris SCI_STATUS scic_controller_initialize(
3911f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T   controller
3912f11c7f63SJim Harris )
3913f11c7f63SJim Harris {
3914f11c7f63SJim Harris    SCI_STATUS status = SCI_FAILURE_INVALID_STATE;
3915f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
3916f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
3917f11c7f63SJim Harris 
3918f11c7f63SJim Harris    SCIC_LOG_TRACE((
3919f11c7f63SJim Harris       sci_base_object_get_logger(controller),
3920f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
3921f11c7f63SJim Harris       "scic_controller_initialize(0x%x, 0x%d) enter\n",
3922f11c7f63SJim Harris       controller
3923f11c7f63SJim Harris    ));
3924f11c7f63SJim Harris 
3925f11c7f63SJim Harris    if (this_controller->state_handlers->parent.initialize_handler != NULL)
3926f11c7f63SJim Harris    {
3927f11c7f63SJim Harris       status = this_controller->state_handlers->parent.initialize_handler(
3928f11c7f63SJim Harris                   (SCI_BASE_CONTROLLER_T *)controller
3929f11c7f63SJim Harris                );
3930f11c7f63SJim Harris    }
3931f11c7f63SJim Harris    else
3932f11c7f63SJim Harris    {
3933f11c7f63SJim Harris       SCIC_LOG_WARNING((
3934f11c7f63SJim Harris          sci_base_object_get_logger(this_controller),
3935f11c7f63SJim Harris          SCIC_LOG_OBJECT_CONTROLLER,
3936f11c7f63SJim Harris          "SCIC Controller initialize operation requested in invalid state %d\n",
3937f11c7f63SJim Harris          sci_base_state_machine_get_state(
3938f11c7f63SJim Harris             scic_sds_controller_get_base_state_machine(this_controller))
3939f11c7f63SJim Harris       ));
3940f11c7f63SJim Harris    }
3941f11c7f63SJim Harris 
3942f11c7f63SJim Harris    return status;
3943f11c7f63SJim Harris }
3944f11c7f63SJim Harris 
3945f11c7f63SJim Harris // ---------------------------------------------------------------------------
3946f11c7f63SJim Harris 
scic_controller_get_suggested_start_timeout(SCI_CONTROLLER_HANDLE_T controller)3947f11c7f63SJim Harris U32 scic_controller_get_suggested_start_timeout(
3948f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T  controller
3949f11c7f63SJim Harris )
3950f11c7f63SJim Harris {
3951f11c7f63SJim Harris    // Validate the user supplied parameters.
3952f11c7f63SJim Harris    if (controller == SCI_INVALID_HANDLE)
3953f11c7f63SJim Harris       return 0;
3954f11c7f63SJim Harris 
3955f11c7f63SJim Harris    // The suggested minimum timeout value for a controller start operation:
3956f11c7f63SJim Harris    //
3957f11c7f63SJim Harris    //     Signature FIS Timeout
3958f11c7f63SJim Harris    //   + Phy Start Timeout
3959f11c7f63SJim Harris    //   + Number of Phy Spin Up Intervals
3960f11c7f63SJim Harris    //   ---------------------------------
3961f11c7f63SJim Harris    //   Number of milliseconds for the controller start operation.
3962f11c7f63SJim Harris    //
3963f11c7f63SJim Harris    // NOTE: The number of phy spin up intervals will be equivalent
3964f11c7f63SJim Harris    //       to the number of phys divided by the number phys allowed
3965f11c7f63SJim Harris    //       per interval - 1 (once OEM parameters are supported).
3966f11c7f63SJim Harris    //       Currently we assume only 1 phy per interval.
3967f11c7f63SJim Harris 
3968f11c7f63SJim Harris    return (SCIC_SDS_SIGNATURE_FIS_TIMEOUT
3969f11c7f63SJim Harris            + SCIC_SDS_CONTROLLER_PHY_START_TIMEOUT
3970f11c7f63SJim Harris            + ((SCI_MAX_PHYS-1) * SCIC_SDS_CONTROLLER_POWER_CONTROL_INTERVAL));
3971f11c7f63SJim Harris }
3972f11c7f63SJim Harris 
3973f11c7f63SJim Harris // ---------------------------------------------------------------------------
3974f11c7f63SJim Harris 
scic_controller_start(SCI_CONTROLLER_HANDLE_T controller,U32 timeout)3975f11c7f63SJim Harris SCI_STATUS scic_controller_start(
3976f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller,
3977f11c7f63SJim Harris    U32 timeout
3978f11c7f63SJim Harris )
3979f11c7f63SJim Harris {
3980f11c7f63SJim Harris    SCI_STATUS status = SCI_FAILURE_INVALID_STATE;
3981f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
3982f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
3983f11c7f63SJim Harris 
3984f11c7f63SJim Harris    SCIC_LOG_TRACE((
3985f11c7f63SJim Harris       sci_base_object_get_logger(controller),
3986f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
3987f11c7f63SJim Harris       "scic_controller_start(0x%x, 0x%d) enter\n",
3988f11c7f63SJim Harris       controller, timeout
3989f11c7f63SJim Harris    ));
3990f11c7f63SJim Harris 
3991f11c7f63SJim Harris    if (this_controller->state_handlers->parent.start_handler != NULL)
3992f11c7f63SJim Harris    {
3993f11c7f63SJim Harris       status = this_controller->state_handlers->parent.start_handler(
3994f11c7f63SJim Harris                   (SCI_BASE_CONTROLLER_T *)controller, timeout
3995f11c7f63SJim Harris                );
3996f11c7f63SJim Harris    }
3997f11c7f63SJim Harris    else
3998f11c7f63SJim Harris    {
3999f11c7f63SJim Harris       SCIC_LOG_WARNING((
4000f11c7f63SJim Harris          sci_base_object_get_logger(this_controller),
4001f11c7f63SJim Harris          SCIC_LOG_OBJECT_CONTROLLER,
4002f11c7f63SJim Harris          "SCIC Controller start operation requested in invalid state %d\n",
4003f11c7f63SJim Harris          sci_base_state_machine_get_state(
4004f11c7f63SJim Harris             scic_sds_controller_get_base_state_machine(this_controller))
4005f11c7f63SJim Harris       ));
4006f11c7f63SJim Harris    }
4007f11c7f63SJim Harris 
4008f11c7f63SJim Harris    return status;
4009f11c7f63SJim Harris }
4010f11c7f63SJim Harris 
4011f11c7f63SJim Harris // ---------------------------------------------------------------------------
4012f11c7f63SJim Harris 
scic_controller_stop(SCI_CONTROLLER_HANDLE_T controller,U32 timeout)4013f11c7f63SJim Harris SCI_STATUS scic_controller_stop(
4014f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller,
4015f11c7f63SJim Harris    U32 timeout
4016f11c7f63SJim Harris )
4017f11c7f63SJim Harris {
4018f11c7f63SJim Harris    SCI_STATUS status = SCI_FAILURE_INVALID_STATE;
4019f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
4020f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
4021f11c7f63SJim Harris 
4022f11c7f63SJim Harris    SCIC_LOG_TRACE((
4023f11c7f63SJim Harris       sci_base_object_get_logger(controller),
4024f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
4025f11c7f63SJim Harris       "scic_controller_stop(0x%x, 0x%d) enter\n",
4026f11c7f63SJim Harris       controller, timeout
4027f11c7f63SJim Harris    ));
4028f11c7f63SJim Harris 
4029f11c7f63SJim Harris    if (this_controller->state_handlers->parent.stop_handler != NULL)
4030f11c7f63SJim Harris    {
4031f11c7f63SJim Harris       status = this_controller->state_handlers->parent.stop_handler(
4032f11c7f63SJim Harris                   (SCI_BASE_CONTROLLER_T *)controller, timeout
4033f11c7f63SJim Harris                );
4034f11c7f63SJim Harris    }
4035f11c7f63SJim Harris    else
4036f11c7f63SJim Harris    {
4037f11c7f63SJim Harris       SCIC_LOG_WARNING((
4038f11c7f63SJim Harris          sci_base_object_get_logger(this_controller),
4039f11c7f63SJim Harris          SCIC_LOG_OBJECT_CONTROLLER,
4040f11c7f63SJim Harris          "SCIC Controller stop operation requested in invalid state %d\n",
4041f11c7f63SJim Harris          sci_base_state_machine_get_state(
4042f11c7f63SJim Harris             scic_sds_controller_get_base_state_machine(this_controller))
4043f11c7f63SJim Harris       ));
4044f11c7f63SJim Harris    }
4045f11c7f63SJim Harris 
4046f11c7f63SJim Harris    return status;
4047f11c7f63SJim Harris }
4048f11c7f63SJim Harris 
4049f11c7f63SJim Harris // ---------------------------------------------------------------------------
4050f11c7f63SJim Harris 
scic_controller_reset(SCI_CONTROLLER_HANDLE_T controller)4051f11c7f63SJim Harris SCI_STATUS scic_controller_reset(
4052f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller
4053f11c7f63SJim Harris )
4054f11c7f63SJim Harris {
4055f11c7f63SJim Harris    SCI_STATUS status = SCI_FAILURE_INVALID_STATE;
4056f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
4057f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
4058f11c7f63SJim Harris 
4059f11c7f63SJim Harris    SCIC_LOG_TRACE((
4060f11c7f63SJim Harris       sci_base_object_get_logger(controller),
4061f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
4062f11c7f63SJim Harris       "scic_controller_reset(0x%x) enter\n",
4063f11c7f63SJim Harris       controller
4064f11c7f63SJim Harris    ));
4065f11c7f63SJim Harris 
4066f11c7f63SJim Harris    if (this_controller->state_handlers->parent.reset_handler != NULL)
4067f11c7f63SJim Harris    {
4068f11c7f63SJim Harris       status = this_controller->state_handlers->parent.reset_handler(
4069f11c7f63SJim Harris                   (SCI_BASE_CONTROLLER_T *)controller
4070f11c7f63SJim Harris                );
4071f11c7f63SJim Harris    }
4072f11c7f63SJim Harris    else
4073f11c7f63SJim Harris    {
4074f11c7f63SJim Harris       SCIC_LOG_WARNING((
4075f11c7f63SJim Harris          sci_base_object_get_logger(this_controller),
4076f11c7f63SJim Harris          SCIC_LOG_OBJECT_CONTROLLER,
4077f11c7f63SJim Harris          "SCIC Controller reset operation requested in invalid state %d\n",
4078f11c7f63SJim Harris          sci_base_state_machine_get_state(
4079f11c7f63SJim Harris             scic_sds_controller_get_base_state_machine(this_controller))
4080f11c7f63SJim Harris       ));
4081f11c7f63SJim Harris    }
4082f11c7f63SJim Harris 
4083f11c7f63SJim Harris    return status;
4084f11c7f63SJim Harris }
4085f11c7f63SJim Harris 
4086f11c7f63SJim Harris // ---------------------------------------------------------------------------
4087f11c7f63SJim Harris 
scic_controller_get_handler_methods(SCIC_INTERRUPT_TYPE interrupt_type,U16 message_count,SCIC_CONTROLLER_HANDLER_METHODS_T * handler_methods)4088f11c7f63SJim Harris SCI_STATUS scic_controller_get_handler_methods(
4089f11c7f63SJim Harris    SCIC_INTERRUPT_TYPE                interrupt_type,
4090f11c7f63SJim Harris    U16                                message_count,
4091f11c7f63SJim Harris    SCIC_CONTROLLER_HANDLER_METHODS_T *handler_methods
4092f11c7f63SJim Harris )
4093f11c7f63SJim Harris {
4094f11c7f63SJim Harris    SCI_STATUS status = SCI_FAILURE_UNSUPPORTED_MESSAGE_COUNT;
4095f11c7f63SJim Harris 
4096f11c7f63SJim Harris    switch (interrupt_type)
4097f11c7f63SJim Harris    {
4098f11c7f63SJim Harris #if !defined(DISABLE_INTERRUPTS)
4099f11c7f63SJim Harris    case SCIC_LEGACY_LINE_INTERRUPT_TYPE:
4100f11c7f63SJim Harris       if (message_count == 0)
4101f11c7f63SJim Harris       {
4102f11c7f63SJim Harris          handler_methods[0].interrupt_handler
4103f11c7f63SJim Harris             = scic_sds_controller_legacy_interrupt_handler;
4104f11c7f63SJim Harris          handler_methods[0].completion_handler
4105f11c7f63SJim Harris             = scic_sds_controller_legacy_completion_handler;
4106f11c7f63SJim Harris 
4107f11c7f63SJim Harris          status = SCI_SUCCESS;
4108f11c7f63SJim Harris       }
4109f11c7f63SJim Harris       break;
4110f11c7f63SJim Harris 
4111f11c7f63SJim Harris    case SCIC_MSIX_INTERRUPT_TYPE:
4112f11c7f63SJim Harris       if (message_count == 1)
4113f11c7f63SJim Harris       {
4114f11c7f63SJim Harris          handler_methods[0].interrupt_handler
4115f11c7f63SJim Harris             = scic_sds_controller_single_vector_interrupt_handler;
4116f11c7f63SJim Harris          handler_methods[0].completion_handler
4117f11c7f63SJim Harris             = scic_sds_controller_single_vector_completion_handler;
4118f11c7f63SJim Harris 
4119f11c7f63SJim Harris          status = SCI_SUCCESS;
4120f11c7f63SJim Harris       }
4121f11c7f63SJim Harris       else if (message_count == 2)
4122f11c7f63SJim Harris       {
4123f11c7f63SJim Harris          handler_methods[0].interrupt_handler
4124f11c7f63SJim Harris             = scic_sds_controller_normal_vector_interrupt_handler;
4125f11c7f63SJim Harris          handler_methods[0].completion_handler
4126f11c7f63SJim Harris             = scic_sds_controller_normal_vector_completion_handler;
4127f11c7f63SJim Harris 
4128f11c7f63SJim Harris          handler_methods[1].interrupt_handler
4129f11c7f63SJim Harris             = scic_sds_controller_error_vector_interrupt_handler;
4130f11c7f63SJim Harris          handler_methods[1].completion_handler
4131f11c7f63SJim Harris             = scic_sds_controller_error_vector_completion_handler;
4132f11c7f63SJim Harris 
4133f11c7f63SJim Harris          status = SCI_SUCCESS;
4134f11c7f63SJim Harris       }
4135f11c7f63SJim Harris       break;
4136f11c7f63SJim Harris #endif // !defined(DISABLE_INTERRUPTS)
4137f11c7f63SJim Harris 
4138f11c7f63SJim Harris    case SCIC_NO_INTERRUPTS:
4139f11c7f63SJim Harris       if (message_count == 0)
4140f11c7f63SJim Harris       {
4141f11c7f63SJim Harris 
4142f11c7f63SJim Harris          handler_methods[0].interrupt_handler
4143f11c7f63SJim Harris             = scic_sds_controller_polling_interrupt_handler;
4144f11c7f63SJim Harris          handler_methods[0].completion_handler
4145f11c7f63SJim Harris             = scic_sds_controller_polling_completion_handler;
4146f11c7f63SJim Harris 
4147f11c7f63SJim Harris          status = SCI_SUCCESS;
4148f11c7f63SJim Harris       }
4149f11c7f63SJim Harris       break;
4150f11c7f63SJim Harris 
4151f11c7f63SJim Harris    default:
4152f11c7f63SJim Harris       status = SCI_FAILURE_INVALID_PARAMETER_VALUE;
4153f11c7f63SJim Harris       break;
4154f11c7f63SJim Harris    }
4155f11c7f63SJim Harris 
4156f11c7f63SJim Harris    return status;
4157f11c7f63SJim Harris }
4158f11c7f63SJim Harris 
4159f11c7f63SJim Harris // ---------------------------------------------------------------------------
4160f11c7f63SJim Harris 
scic_controller_start_io(SCI_CONTROLLER_HANDLE_T controller,SCI_REMOTE_DEVICE_HANDLE_T remote_device,SCI_IO_REQUEST_HANDLE_T io_request,U16 io_tag)4161f11c7f63SJim Harris SCI_IO_STATUS scic_controller_start_io(
4162f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T    controller,
4163f11c7f63SJim Harris    SCI_REMOTE_DEVICE_HANDLE_T remote_device,
4164f11c7f63SJim Harris    SCI_IO_REQUEST_HANDLE_T    io_request,
4165f11c7f63SJim Harris    U16                        io_tag
4166f11c7f63SJim Harris )
4167f11c7f63SJim Harris {
41680f2a8452SJim Harris    SCI_STATUS          status;
4169f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
4170f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
4171f11c7f63SJim Harris 
4172f11c7f63SJim Harris    SCIC_LOG_TRACE((
4173f11c7f63SJim Harris       sci_base_object_get_logger(controller),
4174f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
4175f11c7f63SJim Harris       "scic_controller_start_io(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
4176f11c7f63SJim Harris       controller, remote_device, io_request, io_tag
4177f11c7f63SJim Harris    ));
4178f11c7f63SJim Harris 
4179f11c7f63SJim Harris    status = this_controller->state_handlers->parent.start_io_handler(
4180f11c7f63SJim Harris                &this_controller->parent,
4181f11c7f63SJim Harris                (SCI_BASE_REMOTE_DEVICE_T *)remote_device,
4182f11c7f63SJim Harris                (SCI_BASE_REQUEST_T *)io_request,
4183f11c7f63SJim Harris                io_tag
4184f11c7f63SJim Harris             );
4185f11c7f63SJim Harris 
41860f2a8452SJim Harris    return (SCI_IO_STATUS)status;
4187f11c7f63SJim Harris }
4188f11c7f63SJim Harris 
4189f11c7f63SJim Harris // ---------------------------------------------------------------------------
4190f11c7f63SJim Harris 
scic_controller_terminate_request(SCI_CONTROLLER_HANDLE_T controller,SCI_REMOTE_DEVICE_HANDLE_T remote_device,SCI_IO_REQUEST_HANDLE_T request)4191f11c7f63SJim Harris SCI_STATUS scic_controller_terminate_request(
4192f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T    controller,
4193f11c7f63SJim Harris    SCI_REMOTE_DEVICE_HANDLE_T remote_device,
4194f11c7f63SJim Harris    SCI_IO_REQUEST_HANDLE_T    request
4195f11c7f63SJim Harris )
4196f11c7f63SJim Harris {
4197f11c7f63SJim Harris    SCI_STATUS status;
4198f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
4199f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
4200f11c7f63SJim Harris 
4201f11c7f63SJim Harris    SCIC_LOG_TRACE((
4202f11c7f63SJim Harris       sci_base_object_get_logger(controller),
4203f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
4204f11c7f63SJim Harris       "scic_controller_terminate_request(0x%x, 0x%x, 0x%x) enter\n",
4205f11c7f63SJim Harris       controller, remote_device, request
4206f11c7f63SJim Harris    ));
4207f11c7f63SJim Harris 
4208f11c7f63SJim Harris    status = this_controller->state_handlers->terminate_request_handler(
4209f11c7f63SJim Harris       &this_controller->parent,
4210f11c7f63SJim Harris       (SCI_BASE_REMOTE_DEVICE_T *)remote_device,
4211f11c7f63SJim Harris       (SCI_BASE_REQUEST_T *)request
4212f11c7f63SJim Harris    );
4213f11c7f63SJim Harris 
4214f11c7f63SJim Harris    return status;
4215f11c7f63SJim Harris }
4216f11c7f63SJim Harris 
4217f11c7f63SJim Harris // ---------------------------------------------------------------------------
4218f11c7f63SJim Harris 
scic_controller_complete_io(SCI_CONTROLLER_HANDLE_T controller,SCI_REMOTE_DEVICE_HANDLE_T remote_device,SCI_IO_REQUEST_HANDLE_T io_request)4219f11c7f63SJim Harris SCI_STATUS scic_controller_complete_io(
4220f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller,
4221f11c7f63SJim Harris    SCI_REMOTE_DEVICE_HANDLE_T remote_device,
4222f11c7f63SJim Harris    SCI_IO_REQUEST_HANDLE_T io_request
4223f11c7f63SJim Harris )
4224f11c7f63SJim Harris {
4225f11c7f63SJim Harris    SCI_STATUS status;
4226f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
4227f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
4228f11c7f63SJim Harris 
4229f11c7f63SJim Harris    SCIC_LOG_TRACE((
4230f11c7f63SJim Harris       sci_base_object_get_logger(controller),
4231f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
4232f11c7f63SJim Harris       "scic_controller_complete_io(0x%x, 0x%x, 0x%x) enter\n",
4233f11c7f63SJim Harris       controller, remote_device, io_request
4234f11c7f63SJim Harris    ));
4235f11c7f63SJim Harris 
4236f11c7f63SJim Harris    status = this_controller->state_handlers->parent.complete_io_handler(
4237f11c7f63SJim Harris       &this_controller->parent,
4238f11c7f63SJim Harris       (SCI_BASE_REMOTE_DEVICE_T *)remote_device,
4239f11c7f63SJim Harris       (SCI_BASE_REQUEST_T *)io_request
4240f11c7f63SJim Harris    );
4241f11c7f63SJim Harris 
4242f11c7f63SJim Harris    return status;
4243f11c7f63SJim Harris }
4244f11c7f63SJim Harris 
4245f11c7f63SJim Harris // ---------------------------------------------------------------------------
4246f11c7f63SJim Harris 
4247f11c7f63SJim Harris #if !defined(DISABLE_TASK_MANAGEMENT)
4248f11c7f63SJim Harris 
scic_controller_start_task(SCI_CONTROLLER_HANDLE_T controller,SCI_REMOTE_DEVICE_HANDLE_T remote_device,SCI_TASK_REQUEST_HANDLE_T task_request,U16 task_tag)4249f11c7f63SJim Harris SCI_TASK_STATUS scic_controller_start_task(
4250f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T    controller,
4251f11c7f63SJim Harris    SCI_REMOTE_DEVICE_HANDLE_T remote_device,
4252f11c7f63SJim Harris    SCI_TASK_REQUEST_HANDLE_T  task_request,
4253f11c7f63SJim Harris    U16                        task_tag
4254f11c7f63SJim Harris )
4255f11c7f63SJim Harris {
42560f2a8452SJim Harris    SCI_STATUS             status = SCI_FAILURE_INVALID_STATE;
4257f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
4258f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
4259f11c7f63SJim Harris 
4260f11c7f63SJim Harris    SCIC_LOG_TRACE((
4261f11c7f63SJim Harris       sci_base_object_get_logger(controller),
4262f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
4263f11c7f63SJim Harris       "scic_controller_start_task(0x%x, 0x%x, 0x%x, 0x%x) enter\n",
4264f11c7f63SJim Harris       controller, remote_device, task_request, task_tag
4265f11c7f63SJim Harris    ));
4266f11c7f63SJim Harris 
4267f11c7f63SJim Harris    if (this_controller->state_handlers->parent.start_task_handler != NULL)
4268f11c7f63SJim Harris    {
4269f11c7f63SJim Harris       status = this_controller->state_handlers->parent.start_task_handler(
4270f11c7f63SJim Harris                   &this_controller->parent,
4271f11c7f63SJim Harris                   (SCI_BASE_REMOTE_DEVICE_T *)remote_device,
4272f11c7f63SJim Harris                   (SCI_BASE_REQUEST_T *)task_request,
4273f11c7f63SJim Harris                   task_tag
4274f11c7f63SJim Harris                );
4275f11c7f63SJim Harris    }
4276f11c7f63SJim Harris    else
4277f11c7f63SJim Harris    {
4278f11c7f63SJim Harris       SCIC_LOG_INFO((
4279f11c7f63SJim Harris          sci_base_object_get_logger(controller),
4280f11c7f63SJim Harris          SCIC_LOG_OBJECT_CONTROLLER,
4281f11c7f63SJim Harris          "SCIC Controller starting task from invalid state\n"
4282f11c7f63SJim Harris       ));
4283f11c7f63SJim Harris    }
4284f11c7f63SJim Harris 
42850f2a8452SJim Harris    return (SCI_TASK_STATUS)status;
4286f11c7f63SJim Harris }
4287f11c7f63SJim Harris 
4288f11c7f63SJim Harris // ---------------------------------------------------------------------------
4289f11c7f63SJim Harris 
scic_controller_complete_task(SCI_CONTROLLER_HANDLE_T controller,SCI_REMOTE_DEVICE_HANDLE_T remote_device,SCI_TASK_REQUEST_HANDLE_T task_request)4290f11c7f63SJim Harris SCI_STATUS scic_controller_complete_task(
4291f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T    controller,
4292f11c7f63SJim Harris    SCI_REMOTE_DEVICE_HANDLE_T remote_device,
4293f11c7f63SJim Harris    SCI_TASK_REQUEST_HANDLE_T  task_request
4294f11c7f63SJim Harris )
4295f11c7f63SJim Harris {
4296f11c7f63SJim Harris    SCI_STATUS status = SCI_FAILURE_INVALID_STATE;
4297f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
4298f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
4299f11c7f63SJim Harris 
4300f11c7f63SJim Harris    SCIC_LOG_TRACE((
4301f11c7f63SJim Harris       sci_base_object_get_logger(controller),
4302f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
4303f11c7f63SJim Harris       "scic_controller_complete_task(0x%x, 0x%x, 0x%x) enter\n",
4304f11c7f63SJim Harris       controller, remote_device, task_request
4305f11c7f63SJim Harris    ));
4306f11c7f63SJim Harris 
4307f11c7f63SJim Harris    if (this_controller->state_handlers->parent.complete_task_handler != NULL)
4308f11c7f63SJim Harris    {
4309f11c7f63SJim Harris       status = this_controller->state_handlers->parent.complete_task_handler(
4310f11c7f63SJim Harris                   &this_controller->parent,
4311f11c7f63SJim Harris                   (SCI_BASE_REMOTE_DEVICE_T *)remote_device,
4312f11c7f63SJim Harris                   (SCI_BASE_REQUEST_T *)task_request
4313f11c7f63SJim Harris                );
4314f11c7f63SJim Harris    }
4315f11c7f63SJim Harris    else
4316f11c7f63SJim Harris    {
4317f11c7f63SJim Harris       SCIC_LOG_INFO((
4318f11c7f63SJim Harris          sci_base_object_get_logger(controller),
4319f11c7f63SJim Harris          SCIC_LOG_OBJECT_CONTROLLER,
4320f11c7f63SJim Harris          "SCIC Controller completing task from invalid state\n"
4321f11c7f63SJim Harris       ));
4322f11c7f63SJim Harris    }
4323f11c7f63SJim Harris 
4324f11c7f63SJim Harris    return status;
4325f11c7f63SJim Harris }
4326f11c7f63SJim Harris 
4327f11c7f63SJim Harris #endif // !defined(DISABLE_TASK_MANAGEMENT)
4328f11c7f63SJim Harris 
4329f11c7f63SJim Harris // ---------------------------------------------------------------------------
4330f11c7f63SJim Harris 
scic_controller_get_port_handle(SCI_CONTROLLER_HANDLE_T controller,U8 port_index,SCI_PORT_HANDLE_T * port_handle)4331f11c7f63SJim Harris SCI_STATUS scic_controller_get_port_handle(
4332f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller,
4333f11c7f63SJim Harris    U8                      port_index,
4334f11c7f63SJim Harris    SCI_PORT_HANDLE_T *     port_handle
4335f11c7f63SJim Harris )
4336f11c7f63SJim Harris {
4337f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
4338f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
4339f11c7f63SJim Harris 
4340f11c7f63SJim Harris    SCIC_LOG_TRACE((
4341f11c7f63SJim Harris       sci_base_object_get_logger(controller),
4342f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
4343f11c7f63SJim Harris       "scic_controller_get_port_handle(0x%x, 0x%x, 0x%x) enter\n",
4344f11c7f63SJim Harris       controller, port_index, port_handle
4345f11c7f63SJim Harris    ));
4346f11c7f63SJim Harris 
4347f11c7f63SJim Harris    if (port_index < this_controller->logical_port_entries)
4348f11c7f63SJim Harris    {
4349f11c7f63SJim Harris       *port_handle = &this_controller->port_table[port_index];
4350f11c7f63SJim Harris 
4351f11c7f63SJim Harris       return SCI_SUCCESS;
4352f11c7f63SJim Harris    }
4353f11c7f63SJim Harris 
4354f11c7f63SJim Harris    return SCI_FAILURE_INVALID_PORT;
4355f11c7f63SJim Harris }
4356f11c7f63SJim Harris 
4357f11c7f63SJim Harris // ---------------------------------------------------------------------------
4358f11c7f63SJim Harris 
scic_controller_get_phy_handle(SCI_CONTROLLER_HANDLE_T controller,U8 phy_index,SCI_PHY_HANDLE_T * phy_handle)4359f11c7f63SJim Harris SCI_STATUS scic_controller_get_phy_handle(
4360f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller,
4361f11c7f63SJim Harris    U8                      phy_index,
4362f11c7f63SJim Harris    SCI_PHY_HANDLE_T *      phy_handle
4363f11c7f63SJim Harris )
4364f11c7f63SJim Harris {
4365f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
4366f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
4367f11c7f63SJim Harris 
4368f11c7f63SJim Harris    SCIC_LOG_TRACE((
4369f11c7f63SJim Harris       sci_base_object_get_logger(controller),
4370f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
4371f11c7f63SJim Harris       "scic_controller_get_phy_handle(0x%x, 0x%x, 0x%x) enter\n",
4372f11c7f63SJim Harris       controller, phy_index, phy_handle
4373f11c7f63SJim Harris    ));
4374f11c7f63SJim Harris 
4375f11c7f63SJim Harris    if (phy_index < ARRAY_SIZE(this_controller->phy_table))
4376f11c7f63SJim Harris    {
4377f11c7f63SJim Harris       *phy_handle = &this_controller->phy_table[phy_index];
4378f11c7f63SJim Harris 
4379f11c7f63SJim Harris       return SCI_SUCCESS;
4380f11c7f63SJim Harris    }
4381f11c7f63SJim Harris 
4382f11c7f63SJim Harris    SCIC_LOG_ERROR((
4383f11c7f63SJim Harris       sci_base_object_get_logger(this_controller),
4384f11c7f63SJim Harris       SCIC_LOG_OBJECT_PORT | SCIC_LOG_OBJECT_CONTROLLER,
4385f11c7f63SJim Harris       "Controller:0x%x PhyId:0x%x invalid phy index\n",
4386f11c7f63SJim Harris       this_controller, phy_index
4387f11c7f63SJim Harris    ));
4388f11c7f63SJim Harris 
4389f11c7f63SJim Harris    return SCI_FAILURE_INVALID_PHY;
4390f11c7f63SJim Harris }
4391f11c7f63SJim Harris 
4392f11c7f63SJim Harris // ---------------------------------------------------------------------------
4393f11c7f63SJim Harris 
scic_controller_allocate_io_tag(SCI_CONTROLLER_HANDLE_T controller)4394f11c7f63SJim Harris U16 scic_controller_allocate_io_tag(
4395f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller
4396f11c7f63SJim Harris )
4397f11c7f63SJim Harris {
4398f11c7f63SJim Harris    U16 task_context;
4399f11c7f63SJim Harris    U16 sequence_count;
4400f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
4401f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
4402f11c7f63SJim Harris 
4403f11c7f63SJim Harris    SCIC_LOG_TRACE((
4404f11c7f63SJim Harris       sci_base_object_get_logger(controller),
4405f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
4406f11c7f63SJim Harris       "scic_controller_allocate_io_tag(0x%x) enter\n",
4407f11c7f63SJim Harris       controller
4408f11c7f63SJim Harris    ));
4409f11c7f63SJim Harris 
4410f11c7f63SJim Harris    if (!sci_pool_empty(this_controller->tci_pool))
4411f11c7f63SJim Harris    {
4412f11c7f63SJim Harris       sci_pool_get(this_controller->tci_pool, task_context);
4413f11c7f63SJim Harris 
4414f11c7f63SJim Harris       sequence_count = this_controller->io_request_sequence[task_context];
4415f11c7f63SJim Harris 
4416f11c7f63SJim Harris       return scic_sds_io_tag_construct(sequence_count, task_context);
4417f11c7f63SJim Harris    }
4418f11c7f63SJim Harris 
4419f11c7f63SJim Harris    return SCI_CONTROLLER_INVALID_IO_TAG;
4420f11c7f63SJim Harris }
4421f11c7f63SJim Harris 
4422f11c7f63SJim Harris // ---------------------------------------------------------------------------
4423f11c7f63SJim Harris 
scic_controller_free_io_tag(SCI_CONTROLLER_HANDLE_T controller,U16 io_tag)4424f11c7f63SJim Harris SCI_STATUS scic_controller_free_io_tag(
4425f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller,
4426f11c7f63SJim Harris    U16                     io_tag
4427f11c7f63SJim Harris )
4428f11c7f63SJim Harris {
4429f11c7f63SJim Harris    U16 sequence;
4430f11c7f63SJim Harris    U16 index;
4431f11c7f63SJim Harris 
4432f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
4433f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
4434f11c7f63SJim Harris 
4435f11c7f63SJim Harris    ASSERT(io_tag != SCI_CONTROLLER_INVALID_IO_TAG);
4436f11c7f63SJim Harris 
4437f11c7f63SJim Harris    SCIC_LOG_TRACE((
4438f11c7f63SJim Harris       sci_base_object_get_logger(controller),
4439f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
4440f11c7f63SJim Harris       "scic_controller_free_io_tag(0x%x, 0x%x) enter\n",
4441f11c7f63SJim Harris       controller, io_tag
4442f11c7f63SJim Harris    ));
4443f11c7f63SJim Harris 
4444f11c7f63SJim Harris    sequence = scic_sds_io_tag_get_sequence(io_tag);
4445f11c7f63SJim Harris    index    = scic_sds_io_tag_get_index(io_tag);
4446f11c7f63SJim Harris 
4447f11c7f63SJim Harris    if (!sci_pool_full(this_controller->tci_pool))
4448f11c7f63SJim Harris    {
4449f11c7f63SJim Harris       if (sequence == this_controller->io_request_sequence[index])
4450f11c7f63SJim Harris       {
4451f11c7f63SJim Harris          scic_sds_io_sequence_increment(
4452f11c7f63SJim Harris             this_controller->io_request_sequence[index]);
4453f11c7f63SJim Harris 
4454f11c7f63SJim Harris          sci_pool_put(this_controller->tci_pool, index);
4455f11c7f63SJim Harris 
4456f11c7f63SJim Harris          return SCI_SUCCESS;
4457f11c7f63SJim Harris       }
4458f11c7f63SJim Harris    }
4459f11c7f63SJim Harris 
4460f11c7f63SJim Harris    return SCI_FAILURE_INVALID_IO_TAG;
4461f11c7f63SJim Harris }
4462f11c7f63SJim Harris 
4463f11c7f63SJim Harris // ---------------------------------------------------------------------------
4464f11c7f63SJim Harris 
scic_controller_enable_interrupts(SCI_CONTROLLER_HANDLE_T controller)4465f11c7f63SJim Harris void scic_controller_enable_interrupts(
4466f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller
4467f11c7f63SJim Harris )
4468f11c7f63SJim Harris {
4469f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
4470f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
4471f11c7f63SJim Harris 
4472f11c7f63SJim Harris    ASSERT(this_controller->smu_registers != NULL);
4473f11c7f63SJim Harris 
4474f11c7f63SJim Harris    SMU_IMR_WRITE(this_controller, 0x00000000);
4475f11c7f63SJim Harris }
4476f11c7f63SJim Harris 
4477f11c7f63SJim Harris // ---------------------------------------------------------------------------
4478f11c7f63SJim Harris 
scic_controller_disable_interrupts(SCI_CONTROLLER_HANDLE_T controller)4479f11c7f63SJim Harris void scic_controller_disable_interrupts(
4480f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller
4481f11c7f63SJim Harris )
4482f11c7f63SJim Harris {
4483f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
4484f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
4485f11c7f63SJim Harris 
4486f11c7f63SJim Harris    ASSERT(this_controller->smu_registers != NULL);
4487f11c7f63SJim Harris 
4488f11c7f63SJim Harris    SMU_IMR_WRITE(this_controller, 0xffffffff);
4489f11c7f63SJim Harris }
4490f11c7f63SJim Harris 
4491f11c7f63SJim Harris // ---------------------------------------------------------------------------
4492f11c7f63SJim Harris 
scic_controller_set_mode(SCI_CONTROLLER_HANDLE_T controller,SCI_CONTROLLER_MODE operating_mode)4493f11c7f63SJim Harris SCI_STATUS scic_controller_set_mode(
4494f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T   controller,
4495f11c7f63SJim Harris    SCI_CONTROLLER_MODE       operating_mode
4496f11c7f63SJim Harris )
4497f11c7f63SJim Harris {
4498f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller = (SCIC_SDS_CONTROLLER_T*)controller;
4499f11c7f63SJim Harris    SCI_STATUS             status          = SCI_SUCCESS;
4500f11c7f63SJim Harris 
4501f11c7f63SJim Harris    SCIC_LOG_TRACE((
4502f11c7f63SJim Harris       sci_base_object_get_logger(controller),
4503f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
4504f11c7f63SJim Harris       "scic_controller_set_mode(0x%x, 0x%x) enter\n",
4505f11c7f63SJim Harris       controller, operating_mode
4506f11c7f63SJim Harris    ));
4507f11c7f63SJim Harris 
4508f11c7f63SJim Harris    if (
4509f11c7f63SJim Harris          (this_controller->parent.state_machine.current_state_id
4510f11c7f63SJim Harris           == SCI_BASE_CONTROLLER_STATE_INITIALIZING)
4511f11c7f63SJim Harris       || (this_controller->parent.state_machine.current_state_id
4512f11c7f63SJim Harris           == SCI_BASE_CONTROLLER_STATE_INITIALIZED)
4513f11c7f63SJim Harris       )
4514f11c7f63SJim Harris    {
4515f11c7f63SJim Harris       switch (operating_mode)
4516f11c7f63SJim Harris       {
4517f11c7f63SJim Harris       case SCI_MODE_SPEED:
4518f11c7f63SJim Harris          this_controller->remote_node_entries =
4519f11c7f63SJim Harris             MIN(this_controller->remote_node_entries, SCI_MAX_REMOTE_DEVICES);
4520f11c7f63SJim Harris          this_controller->task_context_entries =
4521f11c7f63SJim Harris             MIN(this_controller->task_context_entries, SCU_IO_REQUEST_COUNT);
4522f11c7f63SJim Harris          this_controller->uf_control.buffers.count =
4523f11c7f63SJim Harris             MIN(this_controller->uf_control.buffers.count, SCU_UNSOLICITED_FRAME_COUNT);
4524f11c7f63SJim Harris          this_controller->completion_event_entries =
4525f11c7f63SJim Harris             MIN(this_controller->completion_event_entries, SCU_EVENT_COUNT);
4526f11c7f63SJim Harris          this_controller->completion_queue_entries =
4527f11c7f63SJim Harris             MIN(this_controller->completion_queue_entries, SCU_COMPLETION_QUEUE_COUNT);
4528f11c7f63SJim Harris 
4529f11c7f63SJim Harris          scic_sds_controller_build_memory_descriptor_table(this_controller);
4530f11c7f63SJim Harris       break;
4531f11c7f63SJim Harris 
4532f11c7f63SJim Harris       case SCI_MODE_SIZE:
4533f11c7f63SJim Harris          this_controller->remote_node_entries =
4534f11c7f63SJim Harris             MIN(this_controller->remote_node_entries, SCI_MIN_REMOTE_DEVICES);
4535f11c7f63SJim Harris          this_controller->task_context_entries =
4536f11c7f63SJim Harris             MIN(this_controller->task_context_entries, SCI_MIN_IO_REQUESTS);
4537f11c7f63SJim Harris          this_controller->uf_control.buffers.count =
4538f11c7f63SJim Harris             MIN(this_controller->uf_control.buffers.count, SCU_MIN_UNSOLICITED_FRAMES);
4539f11c7f63SJim Harris          this_controller->completion_event_entries =
4540f11c7f63SJim Harris             MIN(this_controller->completion_event_entries, SCU_MIN_EVENTS);
4541f11c7f63SJim Harris          this_controller->completion_queue_entries =
4542f11c7f63SJim Harris             MIN(this_controller->completion_queue_entries, SCU_MIN_COMPLETION_QUEUE_ENTRIES);
4543f11c7f63SJim Harris 
4544f11c7f63SJim Harris          scic_sds_controller_build_memory_descriptor_table(this_controller);
4545f11c7f63SJim Harris       break;
4546f11c7f63SJim Harris 
4547f11c7f63SJim Harris       default:
4548f11c7f63SJim Harris          status = SCI_FAILURE_INVALID_PARAMETER_VALUE;
4549f11c7f63SJim Harris       break;
4550f11c7f63SJim Harris       }
4551f11c7f63SJim Harris    }
4552f11c7f63SJim Harris    else
4553f11c7f63SJim Harris       status = SCI_FAILURE_INVALID_STATE;
4554f11c7f63SJim Harris 
4555f11c7f63SJim Harris    return status;
4556f11c7f63SJim Harris }
4557f11c7f63SJim Harris 
4558f11c7f63SJim Harris /**
4559f11c7f63SJim Harris  * This method will reset the controller hardware.
4560f11c7f63SJim Harris  *
4561f11c7f63SJim Harris  * @param[in] this_controller The controller that is to be reset.
4562f11c7f63SJim Harris  */
scic_sds_controller_reset_hardware(SCIC_SDS_CONTROLLER_T * this_controller)4563f11c7f63SJim Harris void scic_sds_controller_reset_hardware(
4564f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T * this_controller
4565f11c7f63SJim Harris )
4566f11c7f63SJim Harris {
4567f11c7f63SJim Harris    // Disable interrupts so we dont take any spurious interrupts
4568f11c7f63SJim Harris    scic_controller_disable_interrupts(this_controller);
4569f11c7f63SJim Harris 
4570f11c7f63SJim Harris    // Reset the SCU
4571f11c7f63SJim Harris    SMU_SMUSRCR_WRITE(this_controller, 0xFFFFFFFF);
4572f11c7f63SJim Harris 
4573f11c7f63SJim Harris    // Delay for 1ms to before clearing the CQP and UFQPR.
4574f11c7f63SJim Harris    scic_cb_stall_execution(1000);
4575f11c7f63SJim Harris 
4576f11c7f63SJim Harris    // The write to the CQGR clears the CQP
4577f11c7f63SJim Harris    SMU_CQGR_WRITE(this_controller, 0x00000000);
4578f11c7f63SJim Harris 
4579f11c7f63SJim Harris    // The write to the UFQGP clears the UFQPR
4580f11c7f63SJim Harris    SCU_UFQGP_WRITE(this_controller, 0x00000000);
4581f11c7f63SJim Harris }
4582f11c7f63SJim Harris 
4583f11c7f63SJim Harris // ---------------------------------------------------------------------------
4584f11c7f63SJim Harris 
scic_user_parameters_set(SCI_CONTROLLER_HANDLE_T controller,SCIC_USER_PARAMETERS_T * scic_parms)4585f11c7f63SJim Harris SCI_STATUS scic_user_parameters_set(
4586f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T   controller,
4587f11c7f63SJim Harris    SCIC_USER_PARAMETERS_T  * scic_parms
4588f11c7f63SJim Harris )
4589f11c7f63SJim Harris {
4590f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T * this_controller = (SCIC_SDS_CONTROLLER_T*)controller;
4591f11c7f63SJim Harris 
4592f11c7f63SJim Harris    if (
4593f11c7f63SJim Harris          (this_controller->parent.state_machine.current_state_id
4594f11c7f63SJim Harris           == SCI_BASE_CONTROLLER_STATE_RESET)
4595f11c7f63SJim Harris       || (this_controller->parent.state_machine.current_state_id
4596f11c7f63SJim Harris           == SCI_BASE_CONTROLLER_STATE_INITIALIZING)
4597f11c7f63SJim Harris       || (this_controller->parent.state_machine.current_state_id
4598f11c7f63SJim Harris           == SCI_BASE_CONTROLLER_STATE_INITIALIZED)
4599f11c7f63SJim Harris       )
4600f11c7f63SJim Harris    {
4601f11c7f63SJim Harris       U16  index;
4602f11c7f63SJim Harris 
4603f11c7f63SJim Harris       // Validate the user parameters.  If they are not legal, then
4604f11c7f63SJim Harris       // return a failure.
4605f11c7f63SJim Harris       for (index = 0; index < SCI_MAX_PHYS; index++)
4606f11c7f63SJim Harris       {
4607f11c7f63SJim Harris          if (!
4608f11c7f63SJim Harris                (  scic_parms->sds1.phys[index].max_speed_generation
4609f11c7f63SJim Harris                   <= SCIC_SDS_PARM_MAX_SPEED
4610f11c7f63SJim Harris                && scic_parms->sds1.phys[index].max_speed_generation
4611f11c7f63SJim Harris                   > SCIC_SDS_PARM_NO_SPEED
4612f11c7f63SJim Harris                )
4613f11c7f63SJim Harris             )
4614f11c7f63SJim Harris             return SCI_FAILURE_INVALID_PARAMETER_VALUE;
4615f11c7f63SJim Harris 
4616f11c7f63SJim Harris          if (
4617f11c7f63SJim Harris                (scic_parms->sds1.phys[index].in_connection_align_insertion_frequency < 3) ||
4618f11c7f63SJim Harris                (scic_parms->sds1.phys[index].align_insertion_frequency == 0) ||
4619f11c7f63SJim Harris                (scic_parms->sds1.phys[index].notify_enable_spin_up_insertion_frequency == 0)
4620f11c7f63SJim Harris             )
4621f11c7f63SJim Harris          {
4622f11c7f63SJim Harris             return SCI_FAILURE_INVALID_PARAMETER_VALUE;
4623f11c7f63SJim Harris          }
4624f11c7f63SJim Harris       }
4625f11c7f63SJim Harris 
4626f11c7f63SJim Harris       if (
4627f11c7f63SJim Harris             (scic_parms->sds1.stp_inactivity_timeout == 0) ||
4628f11c7f63SJim Harris             (scic_parms->sds1.ssp_inactivity_timeout == 0) ||
4629f11c7f63SJim Harris             (scic_parms->sds1.stp_max_occupancy_timeout == 0) ||
4630f11c7f63SJim Harris             (scic_parms->sds1.ssp_max_occupancy_timeout == 0) ||
4631f11c7f63SJim Harris             (scic_parms->sds1.no_outbound_task_timeout == 0)
4632f11c7f63SJim Harris          )
4633f11c7f63SJim Harris       {
4634f11c7f63SJim Harris          return SCI_FAILURE_INVALID_PARAMETER_VALUE;
4635f11c7f63SJim Harris       }
4636f11c7f63SJim Harris 
4637f11c7f63SJim Harris       memcpy(
4638f11c7f63SJim Harris          (&this_controller->user_parameters), scic_parms, sizeof(*scic_parms));
4639f11c7f63SJim Harris 
4640f11c7f63SJim Harris       return SCI_SUCCESS;
4641f11c7f63SJim Harris    }
4642f11c7f63SJim Harris 
4643f11c7f63SJim Harris    return SCI_FAILURE_INVALID_STATE;
4644f11c7f63SJim Harris }
4645f11c7f63SJim Harris 
4646f11c7f63SJim Harris // ---------------------------------------------------------------------------
4647f11c7f63SJim Harris 
scic_user_parameters_get(SCI_CONTROLLER_HANDLE_T controller,SCIC_USER_PARAMETERS_T * scic_parms)4648f11c7f63SJim Harris void scic_user_parameters_get(
4649f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T   controller,
4650f11c7f63SJim Harris    SCIC_USER_PARAMETERS_T   * scic_parms
4651f11c7f63SJim Harris )
4652f11c7f63SJim Harris {
4653f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T * this_controller = (SCIC_SDS_CONTROLLER_T*)controller;
4654f11c7f63SJim Harris 
4655f11c7f63SJim Harris    memcpy(scic_parms, (&this_controller->user_parameters), sizeof(*scic_parms));
4656f11c7f63SJim Harris }
4657f11c7f63SJim Harris 
4658f11c7f63SJim Harris // ---------------------------------------------------------------------------
scic_oem_parameters_set(SCI_CONTROLLER_HANDLE_T controller,SCIC_OEM_PARAMETERS_T * scic_parms,U8 scic_parms_version)4659f11c7f63SJim Harris SCI_STATUS scic_oem_parameters_set(
4660f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T   controller,
4661f11c7f63SJim Harris    SCIC_OEM_PARAMETERS_T   * scic_parms,
4662f11c7f63SJim Harris    U8 scic_parms_version
4663f11c7f63SJim Harris )
4664f11c7f63SJim Harris {
4665f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T * this_controller = (SCIC_SDS_CONTROLLER_T*)controller;
4666f11c7f63SJim Harris    SCI_BIOS_OEM_PARAM_ELEMENT_T *old_oem_params =
4667f11c7f63SJim Harris                 (SCI_BIOS_OEM_PARAM_ELEMENT_T *)(&(scic_parms->sds1));
4668f11c7f63SJim Harris 
4669f11c7f63SJim Harris 
4670f11c7f63SJim Harris    if (
4671f11c7f63SJim Harris          (this_controller->parent.state_machine.current_state_id
4672f11c7f63SJim Harris           == SCI_BASE_CONTROLLER_STATE_RESET)
4673f11c7f63SJim Harris       || (this_controller->parent.state_machine.current_state_id
4674f11c7f63SJim Harris           == SCI_BASE_CONTROLLER_STATE_INITIALIZING)
4675f11c7f63SJim Harris       || (this_controller->parent.state_machine.current_state_id
4676f11c7f63SJim Harris           == SCI_BASE_CONTROLLER_STATE_INITIALIZED)
4677f11c7f63SJim Harris       )
4678f11c7f63SJim Harris    {
4679f11c7f63SJim Harris       U16  index;
4680f11c7f63SJim Harris       U8   combined_phy_mask = 0;
4681f11c7f63SJim Harris 
4682f11c7f63SJim Harris       /*
4683f11c7f63SJim Harris        * Set the OEM parameter version for the controller. This comes
4684f11c7f63SJim Harris        * from the OEM parameter block header or the registry depending
4685f11c7f63SJim Harris        * on what WCDL is set to retrieve.
4686f11c7f63SJim Harris        */
4687f11c7f63SJim Harris       this_controller->oem_parameters_version = scic_parms_version;
4688f11c7f63SJim Harris 
4689f11c7f63SJim Harris       // Validate the oem parameters.  If they are not legal, then
4690f11c7f63SJim Harris       // return a failure.
4691f11c7f63SJim Harris       for(index=0; index<SCI_MAX_PORTS; index++)
4692f11c7f63SJim Harris       {
4693f11c7f63SJim Harris          if (scic_parms->sds1.ports[index].phy_mask > SCIC_SDS_PARM_PHY_MASK_MAX)
4694f11c7f63SJim Harris          {
4695f11c7f63SJim Harris             return SCI_FAILURE_INVALID_PARAMETER_VALUE;
4696f11c7f63SJim Harris          }
4697f11c7f63SJim Harris       }
4698f11c7f63SJim Harris 
4699f11c7f63SJim Harris       for(index=0; index<SCI_MAX_PHYS; index++)
4700f11c7f63SJim Harris       {
4701f11c7f63SJim Harris          if (
4702f11c7f63SJim Harris              scic_parms->sds1.phys[index].sas_address.sci_format.high == 0
4703f11c7f63SJim Harris                  && scic_parms->sds1.phys[index].sas_address.sci_format.low  == 0
4704f11c7f63SJim Harris         )
4705f11c7f63SJim Harris         {
4706f11c7f63SJim Harris             return SCI_FAILURE_INVALID_PARAMETER_VALUE;
4707f11c7f63SJim Harris         }
4708f11c7f63SJim Harris 
4709f11c7f63SJim Harris #if defined(PBG_HBA_A0_BUILD) || defined(PBG_HBA_A2_BUILD) || defined(PBG_HBA_BETA_BUILD) || defined(PBG_BUILD)
4710f11c7f63SJim Harris         if (
4711f11c7f63SJim Harris               (scic_parms->sds1.phys[index].afe_tx_amp_control0 == 0) ||
4712f11c7f63SJim Harris               (scic_parms->sds1.phys[index].afe_tx_amp_control1 == 0) ||
4713f11c7f63SJim Harris               (scic_parms->sds1.phys[index].afe_tx_amp_control2 == 0) ||
4714f11c7f63SJim Harris               (scic_parms->sds1.phys[index].afe_tx_amp_control3 == 0)
4715f11c7f63SJim Harris               )
4716f11c7f63SJim Harris         {
4717f11c7f63SJim Harris            return SCI_FAILURE_INVALID_PARAMETER_VALUE;
4718f11c7f63SJim Harris         }
4719f11c7f63SJim Harris #endif
4720f11c7f63SJim Harris       }
4721f11c7f63SJim Harris 
4722f11c7f63SJim Harris       if (scic_parms->sds1.controller.mode_type == SCIC_PORT_AUTOMATIC_CONFIGURATION_MODE)
4723f11c7f63SJim Harris       {
4724f11c7f63SJim Harris          for(index=0; index<SCI_MAX_PHYS; index++)
4725f11c7f63SJim Harris          {
4726f11c7f63SJim Harris             if (scic_parms->sds1.ports[index].phy_mask != 0)
4727f11c7f63SJim Harris             {
4728f11c7f63SJim Harris                return SCI_FAILURE_INVALID_PARAMETER_VALUE;
4729f11c7f63SJim Harris             }
4730f11c7f63SJim Harris          }
4731f11c7f63SJim Harris       }
4732f11c7f63SJim Harris       else if (scic_parms->sds1.controller.mode_type == SCIC_PORT_MANUAL_CONFIGURATION_MODE)
4733f11c7f63SJim Harris       {
4734f11c7f63SJim Harris          for(index=0; index<SCI_MAX_PHYS; index++)
4735f11c7f63SJim Harris          {
4736f11c7f63SJim Harris             combined_phy_mask |= scic_parms->sds1.ports[index].phy_mask;
4737f11c7f63SJim Harris          }
4738f11c7f63SJim Harris 
4739f11c7f63SJim Harris          if (combined_phy_mask == 0)
4740f11c7f63SJim Harris          {
4741f11c7f63SJim Harris             return SCI_FAILURE_INVALID_PARAMETER_VALUE;
4742f11c7f63SJim Harris          }
4743f11c7f63SJim Harris       }
4744f11c7f63SJim Harris       else
4745f11c7f63SJim Harris       {
4746f11c7f63SJim Harris          return SCI_FAILURE_INVALID_PARAMETER_VALUE;
4747f11c7f63SJim Harris       }
4748f11c7f63SJim Harris 
4749f11c7f63SJim Harris       if (scic_parms->sds1.controller.max_number_concurrent_device_spin_up > MAX_CONCURRENT_DEVICE_SPIN_UP_COUNT)
4750f11c7f63SJim Harris       {
4751f11c7f63SJim Harris          return SCI_FAILURE_INVALID_PARAMETER_VALUE;
4752f11c7f63SJim Harris       }
4753f11c7f63SJim Harris 
4754f11c7f63SJim Harris       if (old_oem_params->controller.do_enable_ssc != 0)
4755f11c7f63SJim Harris       {
4756f11c7f63SJim Harris          if (  (scic_parms_version == SCI_OEM_PARAM_VER_1_0)
4757f11c7f63SJim Harris             && (old_oem_params->controller.do_enable_ssc != 0x01))
4758f11c7f63SJim Harris              return SCI_FAILURE_INVALID_PARAMETER_VALUE;
4759f11c7f63SJim Harris 
4760f11c7f63SJim Harris          if (scic_parms_version >= SCI_OEM_PARAM_VER_1_1)
4761f11c7f63SJim Harris          {
4762f11c7f63SJim Harris             SCI_BIOS_OEM_PARAM_ELEMENT_v_1_1_T *oem_params =
4763f11c7f63SJim Harris                 (SCI_BIOS_OEM_PARAM_ELEMENT_v_1_1_T*)(&(scic_parms->sds1));
4764f11c7f63SJim Harris 
4765f11c7f63SJim Harris             U8 test = oem_params->controller.ssc_sata_tx_spread_level;
4766f11c7f63SJim Harris             if ( !((test == 0x0) || (test == 0x2) || (test == 0x3) ||
4767f11c7f63SJim Harris                  (test == 0x6) || (test == 0x7)) )
4768f11c7f63SJim Harris                 return SCI_FAILURE_INVALID_PARAMETER_VALUE;
4769f11c7f63SJim Harris 
4770f11c7f63SJim Harris             test = oem_params->controller.ssc_sas_tx_spread_level;
4771f11c7f63SJim Harris             if (oem_params->controller.ssc_sas_tx_type == 0)
4772f11c7f63SJim Harris             {
4773f11c7f63SJim Harris                 if ( !((test == 0x0) || (test == 0x2) || (test == 0x3)) )
4774f11c7f63SJim Harris                     return SCI_FAILURE_INVALID_PARAMETER_VALUE;
4775f11c7f63SJim Harris             }
4776f11c7f63SJim Harris             else
4777f11c7f63SJim Harris             if (oem_params->controller.ssc_sas_tx_type == 1)
4778f11c7f63SJim Harris             {
4779f11c7f63SJim Harris                 if ( !((test == 0x0) || (test == 0x3) || (test == 0x6)) )
4780f11c7f63SJim Harris                     return SCI_FAILURE_INVALID_PARAMETER_VALUE;
4781f11c7f63SJim Harris             }
4782f11c7f63SJim Harris          }
4783f11c7f63SJim Harris       }
4784f11c7f63SJim Harris 
4785f11c7f63SJim Harris       memcpy(
4786f11c7f63SJim Harris          (&this_controller->oem_parameters), scic_parms, sizeof(*scic_parms));
4787f11c7f63SJim Harris       return SCI_SUCCESS;
4788f11c7f63SJim Harris    }
4789f11c7f63SJim Harris 
4790f11c7f63SJim Harris    return SCI_FAILURE_INVALID_STATE;
4791f11c7f63SJim Harris }
4792f11c7f63SJim Harris 
4793f11c7f63SJim Harris // ---------------------------------------------------------------------------
4794f11c7f63SJim Harris 
scic_oem_parameters_get(SCI_CONTROLLER_HANDLE_T controller,SCIC_OEM_PARAMETERS_T * scic_parms)4795f11c7f63SJim Harris void scic_oem_parameters_get(
4796f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T   controller,
4797f11c7f63SJim Harris    SCIC_OEM_PARAMETERS_T   * scic_parms
4798f11c7f63SJim Harris )
4799f11c7f63SJim Harris {
4800f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T * this_controller = (SCIC_SDS_CONTROLLER_T*)controller;
4801f11c7f63SJim Harris 
4802f11c7f63SJim Harris    memcpy(scic_parms, (&this_controller->oem_parameters), sizeof(*scic_parms));
4803f11c7f63SJim Harris }
4804f11c7f63SJim Harris 
4805f11c7f63SJim Harris // ---------------------------------------------------------------------------
4806f11c7f63SJim Harris 
4807f11c7f63SJim Harris #if !defined(DISABLE_INTERRUPTS)
4808f11c7f63SJim Harris 
4809f11c7f63SJim Harris #define INTERRUPT_COALESCE_TIMEOUT_BASE_RANGE_LOWER_BOUND_NS 853
4810f11c7f63SJim Harris #define INTERRUPT_COALESCE_TIMEOUT_BASE_RANGE_UPPER_BOUND_NS 1280
4811f11c7f63SJim Harris #define INTERRUPT_COALESCE_TIMEOUT_MAX_US                    2700000
4812f11c7f63SJim Harris #define INTERRUPT_COALESCE_NUMBER_MAX                        256
4813f11c7f63SJim Harris #define INTERRUPT_COALESCE_TIMEOUT_ENCODE_MIN                7
4814f11c7f63SJim Harris #define INTERRUPT_COALESCE_TIMEOUT_ENCODE_MAX                28
4815f11c7f63SJim Harris 
scic_controller_set_interrupt_coalescence(SCI_CONTROLLER_HANDLE_T controller,U32 coalesce_number,U32 coalesce_timeout)4816f11c7f63SJim Harris SCI_STATUS scic_controller_set_interrupt_coalescence(
4817f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T controller,
4818f11c7f63SJim Harris    U32                     coalesce_number,
4819f11c7f63SJim Harris    U32                     coalesce_timeout
4820f11c7f63SJim Harris )
4821f11c7f63SJim Harris {
4822f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T * scic_controller = (SCIC_SDS_CONTROLLER_T *)controller;
4823f11c7f63SJim Harris    U8 timeout_encode = 0;
4824f11c7f63SJim Harris    U32 min = 0;
4825f11c7f63SJim Harris    U32 max = 0;
4826f11c7f63SJim Harris 
4827f11c7f63SJim Harris    //Check if the input parameters fall in the range.
4828f11c7f63SJim Harris    if (coalesce_number > INTERRUPT_COALESCE_NUMBER_MAX)
4829f11c7f63SJim Harris       return SCI_FAILURE_INVALID_PARAMETER_VALUE;
4830f11c7f63SJim Harris 
4831f11c7f63SJim Harris    //  Defined encoding for interrupt coalescing timeout:
4832f11c7f63SJim Harris    //              Value   Min      Max     Units
4833f11c7f63SJim Harris    //              -----   ---      ---     -----
4834f11c7f63SJim Harris    //              0       -        -       Disabled
4835f11c7f63SJim Harris    //              1       13.3     20.0    ns
4836f11c7f63SJim Harris    //              2       26.7     40.0
4837f11c7f63SJim Harris    //              3       53.3     80.0
4838f11c7f63SJim Harris    //              4       106.7    160.0
4839f11c7f63SJim Harris    //              5       213.3    320.0
4840f11c7f63SJim Harris    //              6       426.7    640.0
4841f11c7f63SJim Harris    //              7       853.3    1280.0
4842f11c7f63SJim Harris    //              8       1.7      2.6     us
4843f11c7f63SJim Harris    //              9       3.4      5.1
4844f11c7f63SJim Harris    //              10      6.8      10.2
4845f11c7f63SJim Harris    //              11      13.7     20.5
4846f11c7f63SJim Harris    //              12      27.3     41.0
4847f11c7f63SJim Harris    //              13      54.6     81.9
4848f11c7f63SJim Harris    //              14      109.2    163.8
4849f11c7f63SJim Harris    //              15      218.5    327.7
4850f11c7f63SJim Harris    //              16      436.9    655.4
4851f11c7f63SJim Harris    //              17      873.8    1310.7
4852f11c7f63SJim Harris    //              18      1.7      2.6     ms
4853f11c7f63SJim Harris    //              19      3.5      5.2
4854f11c7f63SJim Harris    //              20      7.0      10.5
4855f11c7f63SJim Harris    //              21      14.0     21.0
4856f11c7f63SJim Harris    //              22      28.0     41.9
4857f11c7f63SJim Harris    //              23      55.9     83.9
4858f11c7f63SJim Harris    //              24      111.8    167.8
4859f11c7f63SJim Harris    //              25      223.7    335.5
4860f11c7f63SJim Harris    //              26      447.4    671.1
4861f11c7f63SJim Harris    //              27      894.8    1342.2
4862f11c7f63SJim Harris    //              28      1.8      2.7     s
4863f11c7f63SJim Harris    //              Others Undefined
4864f11c7f63SJim Harris 
4865f11c7f63SJim Harris    //Use the table above to decide the encode of interrupt coalescing timeout
4866f11c7f63SJim Harris    //value for register writing.
4867f11c7f63SJim Harris    if (coalesce_timeout == 0)
4868f11c7f63SJim Harris       timeout_encode = 0;
4869f11c7f63SJim Harris    else
4870f11c7f63SJim Harris    {
4871f11c7f63SJim Harris       //make the timeout value in unit of (10 ns).
4872f11c7f63SJim Harris       coalesce_timeout = coalesce_timeout * 100;
4873f11c7f63SJim Harris       min = INTERRUPT_COALESCE_TIMEOUT_BASE_RANGE_LOWER_BOUND_NS / 10;
4874f11c7f63SJim Harris       max = INTERRUPT_COALESCE_TIMEOUT_BASE_RANGE_UPPER_BOUND_NS / 10;
4875f11c7f63SJim Harris 
4876f11c7f63SJim Harris       //get the encode of timeout for register writing.
4877f11c7f63SJim Harris       for ( timeout_encode = INTERRUPT_COALESCE_TIMEOUT_ENCODE_MIN;
4878f11c7f63SJim Harris             timeout_encode <= INTERRUPT_COALESCE_TIMEOUT_ENCODE_MAX;
4879f11c7f63SJim Harris             timeout_encode++ )
4880f11c7f63SJim Harris       {
4881f11c7f63SJim Harris          if (min <= coalesce_timeout &&  max > coalesce_timeout)
4882f11c7f63SJim Harris             break;
4883f11c7f63SJim Harris          else if (coalesce_timeout >= max && coalesce_timeout < min*2
4884f11c7f63SJim Harris             && coalesce_timeout <= INTERRUPT_COALESCE_TIMEOUT_MAX_US*100)
4885f11c7f63SJim Harris          {
4886f11c7f63SJim Harris             if ( (coalesce_timeout-max) < (2*min - coalesce_timeout) )
4887f11c7f63SJim Harris                break;
4888f11c7f63SJim Harris             else
4889f11c7f63SJim Harris             {
4890f11c7f63SJim Harris                timeout_encode++;
4891f11c7f63SJim Harris                break;
4892f11c7f63SJim Harris             }
4893f11c7f63SJim Harris          }
4894f11c7f63SJim Harris          else
4895f11c7f63SJim Harris          {
4896f11c7f63SJim Harris             max = max*2;
4897f11c7f63SJim Harris             min = min*2;
4898f11c7f63SJim Harris          }
4899f11c7f63SJim Harris       }
4900f11c7f63SJim Harris 
4901f11c7f63SJim Harris       if ( timeout_encode == INTERRUPT_COALESCE_TIMEOUT_ENCODE_MAX+1 )
4902f11c7f63SJim Harris          //the value is out of range.
4903f11c7f63SJim Harris          return SCI_FAILURE_INVALID_PARAMETER_VALUE;
4904f11c7f63SJim Harris    }
4905f11c7f63SJim Harris 
4906f11c7f63SJim Harris    SMU_ICC_WRITE(
4907f11c7f63SJim Harris       scic_controller,
4908f11c7f63SJim Harris       (SMU_ICC_GEN_VAL(NUMBER, coalesce_number)|
4909f11c7f63SJim Harris        SMU_ICC_GEN_VAL(TIMER, timeout_encode))
4910f11c7f63SJim Harris    );
4911f11c7f63SJim Harris 
4912f11c7f63SJim Harris    scic_controller->interrupt_coalesce_number = (U16)coalesce_number;
4913f11c7f63SJim Harris    scic_controller->interrupt_coalesce_timeout = coalesce_timeout/100;
4914f11c7f63SJim Harris 
4915f11c7f63SJim Harris    return SCI_SUCCESS;
4916f11c7f63SJim Harris }
4917f11c7f63SJim Harris 
4918f11c7f63SJim Harris // ---------------------------------------------------------------------------
4919f11c7f63SJim Harris 
scic_controller_get_interrupt_coalescence(SCI_CONTROLLER_HANDLE_T controller,U32 * coalesce_number,U32 * coalesce_timeout)4920f11c7f63SJim Harris void scic_controller_get_interrupt_coalescence(
4921f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T   controller,
4922f11c7f63SJim Harris    U32                     * coalesce_number,
4923f11c7f63SJim Harris    U32                     * coalesce_timeout
4924f11c7f63SJim Harris )
4925f11c7f63SJim Harris {
4926f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T * scic_controller = (SCIC_SDS_CONTROLLER_T *)controller;
4927f11c7f63SJim Harris    *coalesce_number = scic_controller->interrupt_coalesce_number;
4928f11c7f63SJim Harris    *coalesce_timeout = scic_controller->interrupt_coalesce_timeout;
4929f11c7f63SJim Harris }
4930f11c7f63SJim Harris 
4931f11c7f63SJim Harris #endif // !defined(DISABLE_INTERRUPTS)
4932f11c7f63SJim Harris 
4933f11c7f63SJim Harris // ---------------------------------------------------------------------------
4934f11c7f63SJim Harris 
scic_controller_get_scratch_ram_size(SCI_CONTROLLER_HANDLE_T controller)4935f11c7f63SJim Harris U32 scic_controller_get_scratch_ram_size(
4936f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T   controller
4937f11c7f63SJim Harris )
4938f11c7f63SJim Harris {
4939f11c7f63SJim Harris    return SCU_SCRATCH_RAM_SIZE_IN_DWORDS;
4940f11c7f63SJim Harris }
4941f11c7f63SJim Harris 
4942f11c7f63SJim Harris // ---------------------------------------------------------------------------
4943f11c7f63SJim Harris 
scic_controller_read_scratch_ram_dword(SCI_CONTROLLER_HANDLE_T controller,U32 offset,U32 * value)4944f11c7f63SJim Harris SCI_STATUS scic_controller_read_scratch_ram_dword(
4945f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T   controller,
4946f11c7f63SJim Harris    U32                       offset,
4947f11c7f63SJim Harris    U32                     * value
4948f11c7f63SJim Harris )
4949f11c7f63SJim Harris {
4950f11c7f63SJim Harris    U32 zpt_index;
4951f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T * scic_controller = (SCIC_SDS_CONTROLLER_T *)controller;
4952f11c7f63SJim Harris    U32 status = SMU_SMUCSR_READ(scic_controller);
4953f11c7f63SJim Harris 
4954f11c7f63SJim Harris    //Check if the SCU Scratch RAM been initialized, if not return zeros
4955f11c7f63SJim Harris    if ((status & SCU_RAM_INIT_COMPLETED) != SCU_RAM_INIT_COMPLETED)
4956f11c7f63SJim Harris    {
4957f11c7f63SJim Harris       *value = 0x00000000;
4958f11c7f63SJim Harris       return SCI_SUCCESS;
4959f11c7f63SJim Harris    }
4960f11c7f63SJim Harris 
4961f11c7f63SJim Harris    if (offset < scic_controller_get_scratch_ram_size(controller))
4962f11c7f63SJim Harris    {
4963f11c7f63SJim Harris       if(offset <= SCU_MAX_ZPT_DWORD_INDEX)
4964f11c7f63SJim Harris       {
4965f11c7f63SJim Harris          zpt_index = offset + (offset - (offset % 4)) + 4;
4966f11c7f63SJim Harris 
4967f11c7f63SJim Harris          *value = scu_controller_scratch_ram_register_read(scic_controller,zpt_index);
4968f11c7f63SJim Harris       }
4969f11c7f63SJim Harris       else //offset > SCU_MAX_ZPT_DWORD_INDEX
4970f11c7f63SJim Harris       {
4971f11c7f63SJim Harris          offset = offset - 132;
4972f11c7f63SJim Harris 
4973f11c7f63SJim Harris          zpt_index = offset + (offset - (offset % 4)) + 4;
4974f11c7f63SJim Harris 
4975f11c7f63SJim Harris          *value = scu_controller_scratch_ram_register_read_ext(scic_controller,zpt_index);
4976f11c7f63SJim Harris       }
4977f11c7f63SJim Harris 
4978f11c7f63SJim Harris       return SCI_SUCCESS;
4979f11c7f63SJim Harris    }
4980f11c7f63SJim Harris    else
4981f11c7f63SJim Harris    {
4982f11c7f63SJim Harris       return SCI_FAILURE_INVALID_PARAMETER_VALUE;
4983f11c7f63SJim Harris    }
4984f11c7f63SJim Harris }
4985f11c7f63SJim Harris 
4986f11c7f63SJim Harris // ---------------------------------------------------------------------------
4987f11c7f63SJim Harris 
scic_controller_write_scratch_ram_dword(SCI_CONTROLLER_HANDLE_T controller,U32 offset,U32 value)4988f11c7f63SJim Harris SCI_STATUS scic_controller_write_scratch_ram_dword(
4989f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T   controller,
4990f11c7f63SJim Harris    U32                       offset,
4991f11c7f63SJim Harris    U32                       value
4992f11c7f63SJim Harris )
4993f11c7f63SJim Harris {
4994f11c7f63SJim Harris    U32 zpt_index;
4995f11c7f63SJim Harris 
4996f11c7f63SJim Harris    if (offset < scic_controller_get_scratch_ram_size(controller))
4997f11c7f63SJim Harris    {
4998f11c7f63SJim Harris       SCIC_SDS_CONTROLLER_T * scic_controller = (SCIC_SDS_CONTROLLER_T *)controller;
4999f11c7f63SJim Harris 
5000f11c7f63SJim Harris       if(offset <= SCU_MAX_ZPT_DWORD_INDEX)
5001f11c7f63SJim Harris       {
5002f11c7f63SJim Harris          zpt_index = offset + (offset - (offset % 4)) + 4;
5003f11c7f63SJim Harris 
5004f11c7f63SJim Harris          scu_controller_scratch_ram_register_write(scic_controller,zpt_index,value);
5005f11c7f63SJim Harris       }
5006f11c7f63SJim Harris       else //offset > SCU_MAX_ZPT_DWORD_INDEX
5007f11c7f63SJim Harris       {
5008f11c7f63SJim Harris          offset = offset - 132;
5009f11c7f63SJim Harris 
5010f11c7f63SJim Harris          zpt_index = offset + (offset - (offset % 4)) + 4;
5011f11c7f63SJim Harris 
5012f11c7f63SJim Harris          scu_controller_scratch_ram_register_write_ext(scic_controller,zpt_index,value);
5013f11c7f63SJim Harris 
5014f11c7f63SJim Harris       }
5015f11c7f63SJim Harris 
5016f11c7f63SJim Harris       return SCI_SUCCESS;
5017f11c7f63SJim Harris    }
5018f11c7f63SJim Harris    else
5019f11c7f63SJim Harris    {
5020f11c7f63SJim Harris       return SCI_FAILURE_INVALID_PARAMETER_VALUE;
5021f11c7f63SJim Harris    }
5022f11c7f63SJim Harris }
5023f11c7f63SJim Harris 
5024f11c7f63SJim Harris // ---------------------------------------------------------------------------
5025f11c7f63SJim Harris 
scic_controller_suspend(SCI_CONTROLLER_HANDLE_T controller)5026f11c7f63SJim Harris SCI_STATUS scic_controller_suspend(
5027f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T   controller
5028f11c7f63SJim Harris )
5029f11c7f63SJim Harris {
5030f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T * this_controller = (SCIC_SDS_CONTROLLER_T*)controller;
5031f11c7f63SJim Harris    U8 index;
5032f11c7f63SJim Harris 
5033f11c7f63SJim Harris    // As a precaution, disable interrupts.  The user is required
5034f11c7f63SJim Harris    // to re-enable interrupts if so desired after the call.
5035f11c7f63SJim Harris    scic_controller_disable_interrupts(controller);
5036f11c7f63SJim Harris 
5037f11c7f63SJim Harris    // Stop all the timers
5038f11c7f63SJim Harris    // Maybe change the states of the objects to avoid processing stuff.
5039f11c7f63SJim Harris 
5040f11c7f63SJim Harris 
5041f11c7f63SJim Harris    // Suspend the Ports in order to ensure no unexpected
5042f11c7f63SJim Harris    // frame reception occurs on the links from the target
5043f11c7f63SJim Harris    for (index = 0; index < SCI_MAX_PORTS; index++)
5044f11c7f63SJim Harris       scic_sds_port_suspend_port_task_scheduler(
5045f11c7f63SJim Harris          &(this_controller->port_table[index]));
5046f11c7f63SJim Harris 
5047f11c7f63SJim Harris    // Disable/Reset the completion queue and unsolicited frame
5048f11c7f63SJim Harris    // queue.
5049f11c7f63SJim Harris    SMU_CQGR_WRITE(this_controller, 0x00000000);
5050f11c7f63SJim Harris    SCU_UFQGP_WRITE(this_controller, 0x00000000);
5051f11c7f63SJim Harris 
5052f11c7f63SJim Harris    // Clear any interrupts that may be pending or may have been generated
5053f11c7f63SJim Harris    // by setting CQGR and CQPR back to 0
5054f11c7f63SJim Harris    SMU_ISR_WRITE(this_controller, 0xFFFFFFFF);
5055f11c7f63SJim Harris 
5056f11c7f63SJim Harris    //reset the software get pointer to completion queue.
5057f11c7f63SJim Harris    this_controller->completion_queue_get = 0;
5058f11c7f63SJim Harris 
5059f11c7f63SJim Harris    return SCI_SUCCESS;
5060f11c7f63SJim Harris }
5061f11c7f63SJim Harris 
5062f11c7f63SJim Harris // ---------------------------------------------------------------------------
5063f11c7f63SJim Harris 
scic_controller_resume(SCI_CONTROLLER_HANDLE_T controller)5064f11c7f63SJim Harris SCI_STATUS scic_controller_resume(
5065f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T   controller
5066f11c7f63SJim Harris )
5067f11c7f63SJim Harris {
5068f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T * this_controller = (SCIC_SDS_CONTROLLER_T*)controller;
5069f11c7f63SJim Harris    U8 index;
5070f11c7f63SJim Harris 
5071f11c7f63SJim Harris    // Initialize the completion queue and unsolicited frame queue.
5072f11c7f63SJim Harris    scic_sds_controller_initialize_completion_queue(this_controller);
5073f11c7f63SJim Harris    scic_sds_controller_initialize_unsolicited_frame_queue(this_controller);
5074f11c7f63SJim Harris 
5075f11c7f63SJim Harris    this_controller->restrict_completions = FALSE;
5076f11c7f63SJim Harris 
5077f11c7f63SJim Harris    // Release the port suspensions to allow for further successful
5078f11c7f63SJim Harris    // operation.
5079f11c7f63SJim Harris    for (index = 0; index < SCI_MAX_PORTS; index++)
5080f11c7f63SJim Harris       scic_sds_port_resume_port_task_scheduler(
5081f11c7f63SJim Harris          &(this_controller->port_table[index]));
5082f11c7f63SJim Harris 
5083f11c7f63SJim Harris    //check the link layer status register DWORD sync acquired bit to detect
5084f11c7f63SJim Harris    //link down event. If there is any link down event happened during controller
5085f11c7f63SJim Harris    //suspension, restart phy state machine.
5086f11c7f63SJim Harris    for (index = 0; index < SCI_MAX_PHYS; index ++)
5087f11c7f63SJim Harris    {
5088f11c7f63SJim Harris       SCIC_SDS_PHY_T * curr_phy = &this_controller->phy_table[index];
5089f11c7f63SJim Harris       U32 link_layer_status = SCU_SAS_LLSTA_READ(curr_phy);
5090f11c7f63SJim Harris 
5091f11c7f63SJim Harris       if ((link_layer_status & SCU_SAS_LLSTA_DWORD_SYNCA_BIT) == 0)
5092f11c7f63SJim Harris       {
5093f11c7f63SJim Harris          //Need to put the phy back to start OOB. Then an appropriate link event
5094f11c7f63SJim Harris          //message will be send to scic user.
5095f11c7f63SJim Harris          scic_sds_phy_restart_starting_state(curr_phy);
5096f11c7f63SJim Harris       }
5097f11c7f63SJim Harris    }
5098f11c7f63SJim Harris 
5099f11c7f63SJim Harris    return SCI_SUCCESS;
5100f11c7f63SJim Harris }
5101f11c7f63SJim Harris 
5102f11c7f63SJim Harris // ---------------------------------------------------------------------------
5103f11c7f63SJim Harris 
scic_controller_transition(SCI_CONTROLLER_HANDLE_T controller,BOOL restrict_completions)5104f11c7f63SJim Harris SCI_STATUS scic_controller_transition(
5105f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T   controller,
5106f11c7f63SJim Harris    BOOL                      restrict_completions
5107f11c7f63SJim Harris )
5108f11c7f63SJim Harris {
5109f11c7f63SJim Harris    SCI_STATUS              result = SCI_FAILURE_INVALID_STATE;
5110f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T * this_controller = (SCIC_SDS_CONTROLLER_T*)controller;
5111f11c7f63SJim Harris    U8                      index;
5112f11c7f63SJim Harris 
5113f11c7f63SJim Harris    SCIC_LOG_TRACE((
5114f11c7f63SJim Harris       sci_base_object_get_logger(controller),
5115f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
5116f11c7f63SJim Harris       "scic_controller_transition(0x%x) enter\n",
5117f11c7f63SJim Harris       controller
5118f11c7f63SJim Harris    ));
5119f11c7f63SJim Harris 
5120f11c7f63SJim Harris    if (this_controller->parent.state_machine.current_state_id
5121f11c7f63SJim Harris        == SCI_BASE_CONTROLLER_STATE_READY)
5122f11c7f63SJim Harris    {
5123f11c7f63SJim Harris       // Ensure that there are no outstanding IO operations at this
5124f11c7f63SJim Harris       // time.
5125f11c7f63SJim Harris       for (index = 0; index < SCI_MAX_PORTS; index++)
5126f11c7f63SJim Harris       {
5127f11c7f63SJim Harris          if (this_controller->port_table[index].started_request_count != 0)
5128f11c7f63SJim Harris             return result;
5129f11c7f63SJim Harris       }
5130f11c7f63SJim Harris 
5131f11c7f63SJim Harris       scic_controller_suspend(controller);
5132f11c7f63SJim Harris 
5133f11c7f63SJim Harris       // Loop through the memory descriptor list and reprogram
5134f11c7f63SJim Harris       // the silicon memory registers accordingly.
5135f11c7f63SJim Harris       result = scic_sds_controller_validate_memory_descriptor_table(
5136f11c7f63SJim Harris                   this_controller);
5137f11c7f63SJim Harris       if (result == SCI_SUCCESS)
5138f11c7f63SJim Harris       {
5139f11c7f63SJim Harris          scic_sds_controller_ram_initialization(this_controller);
5140f11c7f63SJim Harris          this_controller->restrict_completions = restrict_completions;
5141f11c7f63SJim Harris       }
5142f11c7f63SJim Harris 
5143f11c7f63SJim Harris       scic_controller_resume(controller);
5144f11c7f63SJim Harris    }
5145f11c7f63SJim Harris 
5146f11c7f63SJim Harris    return result;
5147f11c7f63SJim Harris }
5148f11c7f63SJim Harris 
5149f11c7f63SJim Harris // ---------------------------------------------------------------------------
5150f11c7f63SJim Harris 
scic_controller_get_max_ports(SCI_CONTROLLER_HANDLE_T controller,U8 * count)5151f11c7f63SJim Harris SCI_STATUS scic_controller_get_max_ports(
5152f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T   controller,
5153f11c7f63SJim Harris    U8                      * count
5154f11c7f63SJim Harris )
5155f11c7f63SJim Harris {
5156f11c7f63SJim Harris    *count = SCI_MAX_PORTS;
5157f11c7f63SJim Harris    return SCI_SUCCESS;
5158f11c7f63SJim Harris }
5159f11c7f63SJim Harris 
5160f11c7f63SJim Harris // ---------------------------------------------------------------------------
5161f11c7f63SJim Harris 
scic_controller_get_max_phys(SCI_CONTROLLER_HANDLE_T controller,U8 * count)5162f11c7f63SJim Harris SCI_STATUS scic_controller_get_max_phys(
5163f11c7f63SJim Harris    SCI_CONTROLLER_HANDLE_T   controller,
5164f11c7f63SJim Harris    U8                      * count
5165f11c7f63SJim Harris )
5166f11c7f63SJim Harris {
5167f11c7f63SJim Harris    *count = SCI_MAX_PHYS;
5168f11c7f63SJim Harris    return SCI_SUCCESS;
5169f11c7f63SJim Harris }
5170f11c7f63SJim Harris 
5171f11c7f63SJim Harris 
5172f11c7f63SJim Harris //******************************************************************************
5173f11c7f63SJim Harris //* CONTROLLER STATE MACHINE
5174f11c7f63SJim Harris //******************************************************************************
5175f11c7f63SJim Harris 
5176f11c7f63SJim Harris /**
5177f11c7f63SJim Harris  * This macro returns the maximum number of logical ports supported by the
5178f11c7f63SJim Harris  * hardware. The caller passes in the value read from the device context
5179f11c7f63SJim Harris  * capacity register and this macro will mash and shift the value
5180f11c7f63SJim Harris  * appropriately.
5181f11c7f63SJim Harris  */
5182f11c7f63SJim Harris #define smu_dcc_get_max_ports(dcc_value) \
5183f11c7f63SJim Harris    ( \
5184f11c7f63SJim Harris      (    ((U32)((dcc_value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_LP_MASK)) \
5185f11c7f63SJim Harris        >> SMU_DEVICE_CONTEXT_CAPACITY_MAX_LP_SHIFT ) + 1\
5186f11c7f63SJim Harris    )
5187f11c7f63SJim Harris 
5188f11c7f63SJim Harris /**
5189f11c7f63SJim Harris  * This macro returns the maximum number of task contexts supported by the
5190f11c7f63SJim Harris  * hardware. The caller passes in the value read from the device context
5191f11c7f63SJim Harris  * capacity register and this macro will mash and shift the value
5192f11c7f63SJim Harris  * appropriately.
5193f11c7f63SJim Harris  */
5194f11c7f63SJim Harris #define smu_dcc_get_max_task_context(dcc_value) \
5195f11c7f63SJim Harris    ( \
5196f11c7f63SJim Harris      (   ((U32)((dcc_value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_TC_MASK)) \
5197f11c7f63SJim Harris        >> SMU_DEVICE_CONTEXT_CAPACITY_MAX_TC_SHIFT ) + 1\
5198f11c7f63SJim Harris    )
5199f11c7f63SJim Harris 
5200f11c7f63SJim Harris /**
5201f11c7f63SJim Harris  * This macro returns the maximum number of remote node contexts supported
5202f11c7f63SJim Harris  * by the hardware. The caller passes in the value read from the device
5203f11c7f63SJim Harris  * context capacity register and this macro will mash and shift the value
5204f11c7f63SJim Harris  * appropriately.
5205f11c7f63SJim Harris  */
5206f11c7f63SJim Harris #define smu_dcc_get_max_remote_node_context(dcc_value) \
5207f11c7f63SJim Harris    ( \
5208f11c7f63SJim Harris      (  ( (U32)((dcc_value) & SMU_DEVICE_CONTEXT_CAPACITY_MAX_RNC_MASK) )\
5209f11c7f63SJim Harris        >> SMU_DEVICE_CONTEXT_CAPACITY_MAX_RNC_SHIFT ) + 1\
5210f11c7f63SJim Harris    )
5211f11c7f63SJim Harris 
5212f11c7f63SJim Harris //*****************************************************************************
5213f11c7f63SJim Harris //* DEFAULT STATE HANDLERS
5214f11c7f63SJim Harris //*****************************************************************************
5215f11c7f63SJim Harris 
5216f11c7f63SJim Harris /**
5217f11c7f63SJim Harris  * This method is called when the SCIC_SDS_CONTROLLER default start
5218f11c7f63SJim Harris  * io/task handler is in place.
5219f11c7f63SJim Harris  *    - Issue a warning message
5220f11c7f63SJim Harris  *
5221f11c7f63SJim Harris  * @param[in] controller This is SCI_BASE_CONTROLLER object which is cast
5222f11c7f63SJim Harris  *       into a SCIC_SDS_CONTROLLER object.
5223f11c7f63SJim Harris  * @param[in] remote_device This is SCI_BASE_REMOTE_DEVICE which, if it was
5224f11c7f63SJim Harris  *       used, would be cast to a SCIC_SDS_REMOTE_DEVICE.
5225f11c7f63SJim Harris  * @param[in] io_request This is the SCI_BASE_REQUEST which, if it was used,
5226f11c7f63SJim Harris  *       would be cast to a SCIC_SDS_IO_REQUEST.
5227f11c7f63SJim Harris  * @param[in] io_tag This is the IO tag to be assigned to the IO request or
5228f11c7f63SJim Harris  *       SCI_CONTROLLER_INVALID_IO_TAG.
5229f11c7f63SJim Harris  *
5230f11c7f63SJim Harris  * @return SCI_STATUS
5231f11c7f63SJim Harris  * @retval SCI_FAILURE_INVALID_STATE
5232f11c7f63SJim Harris  */
5233f11c7f63SJim Harris static
scic_sds_controller_default_start_operation_handler(SCI_BASE_CONTROLLER_T * controller,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request,U16 io_tag)5234f11c7f63SJim Harris SCI_STATUS scic_sds_controller_default_start_operation_handler(
5235f11c7f63SJim Harris    SCI_BASE_CONTROLLER_T    *controller,
5236f11c7f63SJim Harris    SCI_BASE_REMOTE_DEVICE_T *remote_device,
5237f11c7f63SJim Harris    SCI_BASE_REQUEST_T       *io_request,
5238f11c7f63SJim Harris    U16                       io_tag
5239f11c7f63SJim Harris )
5240f11c7f63SJim Harris {
5241f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
5242f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
5243f11c7f63SJim Harris 
5244f11c7f63SJim Harris    SCIC_LOG_WARNING((
5245f11c7f63SJim Harris       sci_base_object_get_logger(this_controller),
5246f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
5247f11c7f63SJim Harris       "SCIC Controller requested to start an io/task from invalid state %d\n",
5248f11c7f63SJim Harris       sci_base_state_machine_get_state(
5249f11c7f63SJim Harris          scic_sds_controller_get_base_state_machine(this_controller))
5250f11c7f63SJim Harris    ));
5251f11c7f63SJim Harris 
5252f11c7f63SJim Harris    return SCI_FAILURE_INVALID_STATE;
5253f11c7f63SJim Harris }
5254f11c7f63SJim Harris 
5255f11c7f63SJim Harris /**
5256f11c7f63SJim Harris  * This method is called when the SCIC_SDS_CONTROLLER default
5257f11c7f63SJim Harris  * request handler is in place.
5258f11c7f63SJim Harris  *    - Issue a warning message
5259f11c7f63SJim Harris  *
5260f11c7f63SJim Harris  * @param[in] controller This is SCI_BASE_CONTROLLER object which is cast
5261f11c7f63SJim Harris  *       into a SCIC_SDS_CONTROLLER object.
5262f11c7f63SJim Harris  * @param[in] remote_device This is SCI_BASE_REMOTE_DEVICE which, if it was
5263f11c7f63SJim Harris  *       used, would be cast to a SCIC_SDS_REMOTE_DEVICE.
5264f11c7f63SJim Harris  * @param[in] io_request This is the SCI_BASE_REQUEST which, if it was used,
5265f11c7f63SJim Harris  *       would be cast to a SCIC_SDS_IO_REQUEST.
5266f11c7f63SJim Harris  *
5267f11c7f63SJim Harris  * @return SCI_STATUS
5268f11c7f63SJim Harris  * @retval SCI_FAILURE_INVALID_STATE
5269f11c7f63SJim Harris  */
5270f11c7f63SJim Harris static
scic_sds_controller_default_request_handler(SCI_BASE_CONTROLLER_T * controller,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request)5271f11c7f63SJim Harris SCI_STATUS scic_sds_controller_default_request_handler(
5272f11c7f63SJim Harris    SCI_BASE_CONTROLLER_T    *controller,
5273f11c7f63SJim Harris    SCI_BASE_REMOTE_DEVICE_T *remote_device,
5274f11c7f63SJim Harris    SCI_BASE_REQUEST_T       *io_request
5275f11c7f63SJim Harris )
5276f11c7f63SJim Harris {
5277f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
5278f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
5279f11c7f63SJim Harris 
5280f11c7f63SJim Harris    SCIC_LOG_WARNING((
5281f11c7f63SJim Harris       sci_base_object_get_logger(this_controller),
5282f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
5283f11c7f63SJim Harris       "SCIC Controller request operation from invalid state %d\n",
5284f11c7f63SJim Harris       sci_base_state_machine_get_state(
5285f11c7f63SJim Harris          scic_sds_controller_get_base_state_machine(this_controller))
5286f11c7f63SJim Harris    ));
5287f11c7f63SJim Harris 
5288f11c7f63SJim Harris    return SCI_FAILURE_INVALID_STATE;
5289f11c7f63SJim Harris }
5290f11c7f63SJim Harris 
5291f11c7f63SJim Harris //*****************************************************************************
5292f11c7f63SJim Harris //* GENERAL (COMMON) STATE HANDLERS
5293f11c7f63SJim Harris //*****************************************************************************
5294f11c7f63SJim Harris 
5295f11c7f63SJim Harris /**
5296f11c7f63SJim Harris  * This method is called when the SCIC_SDS_CONTROLLER is in the ready state
5297f11c7f63SJim Harris  * reset handler is in place.
5298f11c7f63SJim Harris  *    - Transition to SCI_BASE_CONTROLLER_STATE_RESETTING
5299f11c7f63SJim Harris  *
5300f11c7f63SJim Harris  * @param[in] controller The SCI_BASE_CONTROLLER object which is cast into a
5301f11c7f63SJim Harris  *       SCIC_SDS_CONTROLLER object.
5302f11c7f63SJim Harris  *
5303f11c7f63SJim Harris  * @return SCI_STATUS
5304f11c7f63SJim Harris  * @retval SCI_SUCCESS
5305f11c7f63SJim Harris  */
5306f11c7f63SJim Harris static
scic_sds_controller_general_reset_handler(SCI_BASE_CONTROLLER_T * controller)5307f11c7f63SJim Harris SCI_STATUS scic_sds_controller_general_reset_handler(
5308f11c7f63SJim Harris    SCI_BASE_CONTROLLER_T *controller
5309f11c7f63SJim Harris )
5310f11c7f63SJim Harris {
5311f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
5312f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
5313f11c7f63SJim Harris 
5314f11c7f63SJim Harris    SCIC_LOG_TRACE((
5315f11c7f63SJim Harris       sci_base_object_get_logger(controller),
5316f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
5317f11c7f63SJim Harris       "scic_sds_controller_resetting_state_enter(0x%x) enter\n",
5318f11c7f63SJim Harris       controller
5319f11c7f63SJim Harris    ));
5320f11c7f63SJim Harris 
5321f11c7f63SJim Harris    //Release resource. So far only resource to be released are timers.
5322f11c7f63SJim Harris    scic_sds_controller_release_resource(this_controller);
5323f11c7f63SJim Harris 
5324f11c7f63SJim Harris    // The reset operation is not a graceful cleanup just perform the state
5325f11c7f63SJim Harris    // transition.
5326f11c7f63SJim Harris    sci_base_state_machine_change_state(
5327f11c7f63SJim Harris       scic_sds_controller_get_base_state_machine(this_controller),
5328f11c7f63SJim Harris       SCI_BASE_CONTROLLER_STATE_RESETTING
5329f11c7f63SJim Harris    );
5330f11c7f63SJim Harris 
5331f11c7f63SJim Harris    return SCI_SUCCESS;
5332f11c7f63SJim Harris }
5333f11c7f63SJim Harris 
5334f11c7f63SJim Harris //*****************************************************************************
5335f11c7f63SJim Harris //* RESET STATE HANDLERS
5336f11c7f63SJim Harris //*****************************************************************************
5337f11c7f63SJim Harris 
5338f11c7f63SJim Harris /**
5339f11c7f63SJim Harris  * This method is the SCIC_SDS_CONTROLLER initialize handler for the reset
5340f11c7f63SJim Harris  * state.
5341f11c7f63SJim Harris  *    - Currently this function does nothing
5342f11c7f63SJim Harris  *
5343f11c7f63SJim Harris  * @param[in] controller This is the SCI_BASE_CONTROLLER object which is cast
5344f11c7f63SJim Harris  *       into a SCIC_SDS_CONTROLLER object.
5345f11c7f63SJim Harris  *
5346f11c7f63SJim Harris  * @return SCI_STATUS
5347f11c7f63SJim Harris  * @retval SCI_FAILURE
5348f11c7f63SJim Harris  *
5349f11c7f63SJim Harris  * @todo This function is not yet implemented and is a valid request from the
5350f11c7f63SJim Harris  *       reset state.
5351f11c7f63SJim Harris  */
5352f11c7f63SJim Harris static
scic_sds_controller_reset_state_initialize_handler(SCI_BASE_CONTROLLER_T * controller)5353f11c7f63SJim Harris SCI_STATUS scic_sds_controller_reset_state_initialize_handler(
5354f11c7f63SJim Harris    SCI_BASE_CONTROLLER_T *controller
5355f11c7f63SJim Harris )
5356f11c7f63SJim Harris {
5357f11c7f63SJim Harris    U32 index;
5358f11c7f63SJim Harris    SCI_STATUS result = SCI_SUCCESS;
5359f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
5360f11c7f63SJim Harris 
5361f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
5362f11c7f63SJim Harris 
5363f11c7f63SJim Harris    SCIC_LOG_TRACE((
5364f11c7f63SJim Harris       sci_base_object_get_logger(controller),
5365f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER | SCIC_LOG_OBJECT_INITIALIZATION,
5366f11c7f63SJim Harris       "scic_sds_controller_reset_state_initialize_handler(0x%x) enter\n",
5367f11c7f63SJim Harris       controller
5368f11c7f63SJim Harris    ));
5369f11c7f63SJim Harris 
5370f11c7f63SJim Harris    sci_base_state_machine_change_state(
5371f11c7f63SJim Harris       scic_sds_controller_get_base_state_machine(this_controller),
5372f11c7f63SJim Harris       SCI_BASE_CONTROLLER_STATE_INITIALIZING
5373f11c7f63SJim Harris    );
5374f11c7f63SJim Harris 
5375f11c7f63SJim Harris    this_controller->timeout_timer = scic_cb_timer_create(
5376f11c7f63SJim Harris       controller,
5377f11c7f63SJim Harris       scic_sds_controller_timeout_handler,
5378f11c7f63SJim Harris       controller
5379f11c7f63SJim Harris    );
5380f11c7f63SJim Harris 
5381f11c7f63SJim Harris    scic_sds_controller_initialize_power_control(this_controller);
5382f11c7f63SJim Harris 
5383f11c7f63SJim Harris    /// todo: This should really be done in the reset state enter but
5384f11c7f63SJim Harris    ///       the controller has not yet been initialized before getting
5385f11c7f63SJim Harris    ///       to the reset enter state so the PCI BAR is not yet assigned
5386f11c7f63SJim Harris    scic_sds_controller_reset_hardware(this_controller);
5387f11c7f63SJim Harris 
5388f11c7f63SJim Harris #if defined(ARLINGTON_BUILD)
5389f11c7f63SJim Harris    scic_sds_controller_lex_atux_initialization(this_controller);
5390f11c7f63SJim Harris #elif    defined(PLEASANT_RIDGE_BUILD) \
5391f11c7f63SJim Harris       || defined(PBG_HBA_A0_BUILD) \
5392f11c7f63SJim Harris       || defined(PBG_HBA_A2_BUILD)
5393f11c7f63SJim Harris    scic_sds_controller_afe_initialization(this_controller);
5394f11c7f63SJim Harris #elif defined(PBG_HBA_BETA_BUILD) || defined(PBG_BUILD)
5395f11c7f63SJim Harris    // There is nothing to do here for B0 since we do not have to
5396f11c7f63SJim Harris    // program the AFE registers.
5397f11c7f63SJim Harris    /// @todo The AFE settings are supposed to be correct for the B0 but
5398f11c7f63SJim Harris    ///       presently they seem to be wrong.
5399f11c7f63SJim Harris    scic_sds_controller_afe_initialization(this_controller);
5400f11c7f63SJim Harris #else  // !defined(ARLINGTON_BUILD) && !defined(PLEASANT_RIDGE_BUILD)
5401f11c7f63SJim Harris    // What other systems do we want to add here?
5402f11c7f63SJim Harris #endif // !defined(ARLINGTON_BUILD) && !defined(PLEASANT_RIDGE_BUILD)
5403f11c7f63SJim Harris 
5404f11c7f63SJim Harris    if (SCI_SUCCESS == result)
5405f11c7f63SJim Harris    {
5406f11c7f63SJim Harris       U32 status;
5407f11c7f63SJim Harris       U32 terminate_loop;
5408f11c7f63SJim Harris 
5409f11c7f63SJim Harris       // Take the hardware out of reset
5410f11c7f63SJim Harris       SMU_SMUSRCR_WRITE(this_controller, 0x00000000);
5411f11c7f63SJim Harris 
5412f11c7f63SJim Harris       /// @todo Provide meaningfull error code for hardware failure
5413f11c7f63SJim Harris       //result = SCI_FAILURE_CONTROLLER_HARDWARE;
5414f11c7f63SJim Harris       result = SCI_FAILURE;
5415f11c7f63SJim Harris       terminate_loop = 100;
5416f11c7f63SJim Harris 
5417f11c7f63SJim Harris       while (terminate_loop-- && (result != SCI_SUCCESS))
5418f11c7f63SJim Harris       {
5419f11c7f63SJim Harris          // Loop until the hardware reports success
5420f11c7f63SJim Harris          scic_cb_stall_execution(SCU_CONTEXT_RAM_INIT_STALL_TIME);
5421f11c7f63SJim Harris          status = SMU_SMUCSR_READ(this_controller);
5422f11c7f63SJim Harris 
5423f11c7f63SJim Harris          if ((status & SCU_RAM_INIT_COMPLETED) == SCU_RAM_INIT_COMPLETED)
5424f11c7f63SJim Harris          {
5425f11c7f63SJim Harris             result = SCI_SUCCESS;
5426f11c7f63SJim Harris          }
5427f11c7f63SJim Harris       }
5428f11c7f63SJim Harris    }
5429f11c7f63SJim Harris 
5430f11c7f63SJim Harris #ifdef ARLINGTON_BUILD
5431f11c7f63SJim Harris    scic_sds_controller_enable_chipwatch(this_controller);
5432f11c7f63SJim Harris #endif
5433f11c7f63SJim Harris 
5434f11c7f63SJim Harris    if (result == SCI_SUCCESS)
5435f11c7f63SJim Harris    {
5436f11c7f63SJim Harris       U32 max_supported_ports;
5437f11c7f63SJim Harris       U32 max_supported_devices;
5438f11c7f63SJim Harris       U32 max_supported_io_requests;
5439f11c7f63SJim Harris       U32 device_context_capacity;
5440f11c7f63SJim Harris 
5441f11c7f63SJim Harris       // Determine what are the actaul device capacities that the
5442f11c7f63SJim Harris       // hardware will support
5443f11c7f63SJim Harris       device_context_capacity = SMU_DCC_READ(this_controller);
5444f11c7f63SJim Harris 
5445f11c7f63SJim Harris       max_supported_ports =
5446f11c7f63SJim Harris          smu_dcc_get_max_ports(device_context_capacity);
5447f11c7f63SJim Harris       max_supported_devices =
5448f11c7f63SJim Harris          smu_dcc_get_max_remote_node_context(device_context_capacity);
5449f11c7f63SJim Harris       max_supported_io_requests =
5450f11c7f63SJim Harris          smu_dcc_get_max_task_context(device_context_capacity);
5451f11c7f63SJim Harris 
5452f11c7f63SJim Harris       // Make all PEs that are unassigned match up with the logical ports
5453f11c7f63SJim Harris       for (index = 0; index < max_supported_ports; index++)
5454f11c7f63SJim Harris       {
5455f11c7f63SJim Harris          scu_register_write(
5456f11c7f63SJim Harris             this_controller,
5457f11c7f63SJim Harris             this_controller->scu_registers->peg0.ptsg.protocol_engine[index],
5458f11c7f63SJim Harris             index
5459f11c7f63SJim Harris          );
5460f11c7f63SJim Harris       }
5461f11c7f63SJim Harris 
5462f11c7f63SJim Harris       // Now that we have the correct hardware reported minimum values
5463f11c7f63SJim Harris       // build the MDL for the controller.  Default to a performance
5464f11c7f63SJim Harris       // configuration.
5465f11c7f63SJim Harris       scic_controller_set_mode(this_controller, SCI_MODE_SPEED);
5466f11c7f63SJim Harris 
5467f11c7f63SJim Harris       // Record the smaller of the two capacity values
5468f11c7f63SJim Harris       this_controller->logical_port_entries =
5469f11c7f63SJim Harris          MIN(max_supported_ports, this_controller->logical_port_entries);
5470f11c7f63SJim Harris 
5471f11c7f63SJim Harris       this_controller->task_context_entries =
5472f11c7f63SJim Harris          MIN(max_supported_io_requests, this_controller->task_context_entries);
5473f11c7f63SJim Harris 
5474f11c7f63SJim Harris       this_controller->remote_node_entries =
5475f11c7f63SJim Harris          MIN(max_supported_devices, this_controller->remote_node_entries);
5476f11c7f63SJim Harris    }
5477f11c7f63SJim Harris 
5478f11c7f63SJim Harris    // Initialize hardware PCI Relaxed ordering in DMA engines
5479f11c7f63SJim Harris    if (result == SCI_SUCCESS)
5480f11c7f63SJim Harris    {
5481f11c7f63SJim Harris       U32 dma_configuration;
5482f11c7f63SJim Harris 
5483f11c7f63SJim Harris       // Configure the payload DMA
5484f11c7f63SJim Harris       dma_configuration = SCU_PDMACR_READ(this_controller);
5485f11c7f63SJim Harris       dma_configuration |= SCU_PDMACR_GEN_BIT(PCI_RELAXED_ORDERING_ENABLE);
5486f11c7f63SJim Harris       SCU_PDMACR_WRITE(this_controller, dma_configuration);
5487f11c7f63SJim Harris 
5488f11c7f63SJim Harris       // Configure the control DMA
5489f11c7f63SJim Harris       dma_configuration = SCU_CDMACR_READ(this_controller);
5490f11c7f63SJim Harris       dma_configuration |= SCU_CDMACR_GEN_BIT(PCI_RELAXED_ORDERING_ENABLE);
5491f11c7f63SJim Harris       SCU_CDMACR_WRITE(this_controller, dma_configuration);
5492f11c7f63SJim Harris    }
5493f11c7f63SJim Harris 
5494f11c7f63SJim Harris    // Initialize the PHYs before the PORTs because the PHY registers
5495f11c7f63SJim Harris    // are accessed during the port initialization.
5496f11c7f63SJim Harris    if (result == SCI_SUCCESS)
5497f11c7f63SJim Harris    {
5498f11c7f63SJim Harris       // Initialize the phys
5499f11c7f63SJim Harris       for (index = 0;
5500f11c7f63SJim Harris            (result == SCI_SUCCESS) && (index < SCI_MAX_PHYS);
5501f11c7f63SJim Harris            index++)
5502f11c7f63SJim Harris       {
5503f11c7f63SJim Harris          result = scic_sds_phy_initialize(
5504f11c7f63SJim Harris             &this_controller->phy_table[index],
5505f11c7f63SJim Harris             &this_controller->scu_registers->peg0.pe[index].tl,
5506f11c7f63SJim Harris             &this_controller->scu_registers->peg0.pe[index].ll
5507f11c7f63SJim Harris          );
5508f11c7f63SJim Harris       }
5509f11c7f63SJim Harris    }
5510f11c7f63SJim Harris 
5511f11c7f63SJim Harris    //Initialize the SGPIO Unit for HARDWARE controlled SGPIO
5512f11c7f63SJim Harris    if(result == SCI_SUCCESS)
5513f11c7f63SJim Harris    {
5514f11c7f63SJim Harris       scic_sgpio_hardware_initialize(this_controller);
5515f11c7f63SJim Harris    }
5516f11c7f63SJim Harris 
5517f11c7f63SJim Harris    if (result == SCI_SUCCESS)
5518f11c7f63SJim Harris    {
5519f11c7f63SJim Harris       // Initialize the logical ports
5520f11c7f63SJim Harris       for (index = 0;
5521f11c7f63SJim Harris               (index < this_controller->logical_port_entries)
5522f11c7f63SJim Harris            && (result == SCI_SUCCESS);
5523f11c7f63SJim Harris            index++)
5524f11c7f63SJim Harris       {
5525f11c7f63SJim Harris          result = scic_sds_port_initialize(
5526f11c7f63SJim Harris             &this_controller->port_table[index],
5527f11c7f63SJim Harris             &this_controller->scu_registers->peg0.ptsg.port[index],
5528f11c7f63SJim Harris             &this_controller->scu_registers->peg0.ptsg.protocol_engine,
5529f11c7f63SJim Harris             &this_controller->scu_registers->peg0.viit[index]
5530f11c7f63SJim Harris          );
5531f11c7f63SJim Harris       }
5532f11c7f63SJim Harris    }
5533f11c7f63SJim Harris 
5534f11c7f63SJim Harris    if (SCI_SUCCESS == result)
5535f11c7f63SJim Harris    {
5536f11c7f63SJim Harris       result = scic_sds_port_configuration_agent_initialize(
5537f11c7f63SJim Harris                   this_controller,
5538f11c7f63SJim Harris                   &this_controller->port_agent
5539f11c7f63SJim Harris                );
5540f11c7f63SJim Harris    }
5541f11c7f63SJim Harris 
5542f11c7f63SJim Harris    // Advance the controller state machine
5543f11c7f63SJim Harris    if (result == SCI_SUCCESS)
5544f11c7f63SJim Harris    {
5545f11c7f63SJim Harris       sci_base_state_machine_change_state(
5546f11c7f63SJim Harris          scic_sds_controller_get_base_state_machine(this_controller),
5547f11c7f63SJim Harris          SCI_BASE_CONTROLLER_STATE_INITIALIZED
5548f11c7f63SJim Harris       );
5549f11c7f63SJim Harris    }
5550f11c7f63SJim Harris    else
5551f11c7f63SJim Harris    {
5552f11c7f63SJim Harris       //stay in the same state and release the resource
5553f11c7f63SJim Harris       scic_sds_controller_release_resource(this_controller);
5554f11c7f63SJim Harris 
5555f11c7f63SJim Harris       SCIC_LOG_TRACE((
5556f11c7f63SJim Harris          sci_base_object_get_logger(controller),
5557f11c7f63SJim Harris          SCIC_LOG_OBJECT_CONTROLLER | SCIC_LOG_OBJECT_INITIALIZATION,
5558f11c7f63SJim Harris          "Invalid Port Configuration from scic_sds_controller_reset_state_initialize_handler(0x%x) \n",
5559f11c7f63SJim Harris          controller
5560f11c7f63SJim Harris       ));
5561f11c7f63SJim Harris 
5562f11c7f63SJim Harris    }
5563f11c7f63SJim Harris 
5564f11c7f63SJim Harris    return result;
5565f11c7f63SJim Harris }
5566f11c7f63SJim Harris 
5567f11c7f63SJim Harris //*****************************************************************************
5568f11c7f63SJim Harris //* INITIALIZED STATE HANDLERS
5569f11c7f63SJim Harris //*****************************************************************************
5570f11c7f63SJim Harris 
5571f11c7f63SJim Harris /**
5572f11c7f63SJim Harris  * This method is the SCIC_SDS_CONTROLLER start handler for the initialized
5573f11c7f63SJim Harris  * state.
5574f11c7f63SJim Harris  *    - Validate we have a good memory descriptor table
5575f11c7f63SJim Harris  *    - Initialze the physical memory before programming the hardware
5576f11c7f63SJim Harris  *    - Program the SCU hardware with the physical memory addresses passed in
5577f11c7f63SJim Harris  *      the memory descriptor table.
5578f11c7f63SJim Harris  *    - Initialzie the TCi pool
5579f11c7f63SJim Harris  *    - Initialize the RNi pool
5580f11c7f63SJim Harris  *    - Initialize the completion queue
5581f11c7f63SJim Harris  *    - Initialize the unsolicited frame data
5582f11c7f63SJim Harris  *    - Take the SCU port task scheduler out of reset
5583f11c7f63SJim Harris  *    - Start the first phy object.
5584f11c7f63SJim Harris  *    - Transition to SCI_BASE_CONTROLLER_STATE_STARTING.
5585f11c7f63SJim Harris  *
5586f11c7f63SJim Harris  * @param[in] controller This is the SCI_BASE_CONTROLLER object which is cast
5587f11c7f63SJim Harris  *       into a SCIC_SDS_CONTROLLER object.
5588f11c7f63SJim Harris  * @param[in] timeout This is the allowed time for the controller object to
5589f11c7f63SJim Harris  *       reach the started state.
5590f11c7f63SJim Harris  *
5591f11c7f63SJim Harris  * @return SCI_STATUS
5592f11c7f63SJim Harris  * @retval SCI_SUCCESS if all of the controller start operations complete
5593f11c7f63SJim Harris  * @retval SCI_FAILURE_UNSUPPORTED_INFORMATION_FIELD if one or more of the
5594f11c7f63SJim Harris  *         memory descriptor fields is invalid.
5595f11c7f63SJim Harris  */
5596f11c7f63SJim Harris static
scic_sds_controller_initialized_state_start_handler(SCI_BASE_CONTROLLER_T * controller,U32 timeout)5597f11c7f63SJim Harris SCI_STATUS scic_sds_controller_initialized_state_start_handler(
5598f11c7f63SJim Harris    SCI_BASE_CONTROLLER_T * controller,
5599f11c7f63SJim Harris    U32                     timeout
5600f11c7f63SJim Harris )
5601f11c7f63SJim Harris {
5602f11c7f63SJim Harris    U16                     index;
5603f11c7f63SJim Harris    SCI_STATUS              result;
5604f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T * this_controller;
5605f11c7f63SJim Harris 
5606f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
5607f11c7f63SJim Harris 
5608f11c7f63SJim Harris    // Make sure that the SCI User filled in the memory descriptor table correctly
5609f11c7f63SJim Harris    result = scic_sds_controller_validate_memory_descriptor_table(this_controller);
5610f11c7f63SJim Harris 
5611f11c7f63SJim Harris    if (result == SCI_SUCCESS)
5612f11c7f63SJim Harris    {
5613f11c7f63SJim Harris       // The memory descriptor list looks good so program the hardware
5614f11c7f63SJim Harris       scic_sds_controller_ram_initialization(this_controller);
5615f11c7f63SJim Harris    }
5616f11c7f63SJim Harris 
5617f11c7f63SJim Harris    if (SCI_SUCCESS == result)
5618f11c7f63SJim Harris    {
5619f11c7f63SJim Harris       // Build the TCi free pool
5620f11c7f63SJim Harris       sci_pool_initialize(this_controller->tci_pool);
5621f11c7f63SJim Harris       for (index = 0; index < this_controller->task_context_entries; index++)
5622f11c7f63SJim Harris       {
5623f11c7f63SJim Harris          sci_pool_put(this_controller->tci_pool, index);
5624f11c7f63SJim Harris       }
5625f11c7f63SJim Harris 
5626f11c7f63SJim Harris       // Build the RNi free pool
5627f11c7f63SJim Harris       scic_sds_remote_node_table_initialize(
5628f11c7f63SJim Harris          &this_controller->available_remote_nodes,
5629f11c7f63SJim Harris          this_controller->remote_node_entries
5630f11c7f63SJim Harris       );
5631f11c7f63SJim Harris    }
5632f11c7f63SJim Harris 
5633f11c7f63SJim Harris    if (SCI_SUCCESS == result)
5634f11c7f63SJim Harris    {
5635f11c7f63SJim Harris       // Before anything else lets make sure we will not be interrupted
5636f11c7f63SJim Harris       // by the hardware.
5637f11c7f63SJim Harris       scic_controller_disable_interrupts(controller);
5638f11c7f63SJim Harris 
5639f11c7f63SJim Harris       // Enable the port task scheduler
5640f11c7f63SJim Harris       scic_sds_controller_enable_port_task_scheduler(this_controller);
5641f11c7f63SJim Harris 
5642f11c7f63SJim Harris       // Assign all the task entries to this controller physical function
5643f11c7f63SJim Harris       scic_sds_controller_assign_task_entries(this_controller);
5644f11c7f63SJim Harris 
5645f11c7f63SJim Harris       // Now initialze the completion queue
5646f11c7f63SJim Harris       scic_sds_controller_initialize_completion_queue(this_controller);
5647f11c7f63SJim Harris 
5648f11c7f63SJim Harris       // Initialize the unsolicited frame queue for use
5649f11c7f63SJim Harris       scic_sds_controller_initialize_unsolicited_frame_queue(this_controller);
5650f11c7f63SJim Harris 
5651f11c7f63SJim Harris       // Setup the phy start timer
5652f11c7f63SJim Harris       result = scic_sds_controller_initialize_phy_startup(this_controller);
5653f11c7f63SJim Harris    }
5654f11c7f63SJim Harris 
5655f11c7f63SJim Harris    // Start all of the ports on this controller
5656f11c7f63SJim Harris    for (
5657f11c7f63SJim Harris           index = 0;
5658f11c7f63SJim Harris           (index < this_controller->logical_port_entries) && (result == SCI_SUCCESS);
5659f11c7f63SJim Harris           index++
5660f11c7f63SJim Harris        )
5661f11c7f63SJim Harris    {
5662f11c7f63SJim Harris       result = this_controller->port_table[index].
5663f11c7f63SJim Harris          state_handlers->parent.start_handler(&this_controller->port_table[index].parent);
5664f11c7f63SJim Harris    }
5665f11c7f63SJim Harris 
5666f11c7f63SJim Harris    if (SCI_SUCCESS == result)
5667f11c7f63SJim Harris    {
5668f11c7f63SJim Harris       scic_sds_controller_start_next_phy(this_controller);
5669f11c7f63SJim Harris 
5670f11c7f63SJim Harris       // See if the user requested to timeout this operation.
5671f11c7f63SJim Harris       if (timeout != 0)
5672f11c7f63SJim Harris          scic_cb_timer_start(controller, this_controller->timeout_timer, timeout);
5673f11c7f63SJim Harris 
5674f11c7f63SJim Harris       sci_base_state_machine_change_state(
5675f11c7f63SJim Harris          scic_sds_controller_get_base_state_machine(this_controller),
5676f11c7f63SJim Harris          SCI_BASE_CONTROLLER_STATE_STARTING
5677f11c7f63SJim Harris       );
5678f11c7f63SJim Harris    }
5679f11c7f63SJim Harris 
5680f11c7f63SJim Harris    return result;
5681f11c7f63SJim Harris }
5682f11c7f63SJim Harris 
5683f11c7f63SJim Harris //*****************************************************************************
5684f11c7f63SJim Harris //* STARTING STATE HANDLERS
5685f11c7f63SJim Harris //*****************************************************************************
5686f11c7f63SJim Harris 
5687f11c7f63SJim Harris /**
5688f11c7f63SJim Harris  * This method is called when the SCIC_SDS_CONTROLLER is in the starting state
5689f11c7f63SJim Harris  * link up handler is called.  This method will perform the following:
5690f11c7f63SJim Harris  *    - Stop the phy timer
5691f11c7f63SJim Harris  *    - Start the next phy
5692f11c7f63SJim Harris  *    - Report the link up condition to the port object
5693f11c7f63SJim Harris  *
5694f11c7f63SJim Harris  * @param[in] controller This is SCIC_SDS_CONTROLLER which receives the link up
5695f11c7f63SJim Harris  *       notification.
5696f11c7f63SJim Harris  * @param[in] port This is SCIC_SDS_PORT with which the phy is associated.
5697f11c7f63SJim Harris  * @param[in] phy This is the SCIC_SDS_PHY which has gone link up.
5698f11c7f63SJim Harris  *
5699f11c7f63SJim Harris  * @return none
5700f11c7f63SJim Harris  */
5701f11c7f63SJim Harris static
scic_sds_controller_starting_state_link_up_handler(SCIC_SDS_CONTROLLER_T * this_controller,SCIC_SDS_PORT_T * port,SCIC_SDS_PHY_T * phy)5702f11c7f63SJim Harris void scic_sds_controller_starting_state_link_up_handler(
5703f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller,
5704f11c7f63SJim Harris    SCIC_SDS_PORT_T       *port,
5705f11c7f63SJim Harris    SCIC_SDS_PHY_T        *phy
5706f11c7f63SJim Harris )
5707f11c7f63SJim Harris {
5708f11c7f63SJim Harris    scic_sds_controller_phy_timer_stop(this_controller);
5709f11c7f63SJim Harris 
5710f11c7f63SJim Harris    this_controller->port_agent.link_up_handler(
5711f11c7f63SJim Harris       this_controller, &this_controller->port_agent, port, phy
5712f11c7f63SJim Harris    );
5713f11c7f63SJim Harris    //scic_sds_port_link_up(port, phy);
5714f11c7f63SJim Harris 
5715f11c7f63SJim Harris    scic_sds_controller_start_next_phy(this_controller);
5716f11c7f63SJim Harris }
5717f11c7f63SJim Harris 
5718f11c7f63SJim Harris /**
5719f11c7f63SJim Harris  * This method is called when the SCIC_SDS_CONTROLLER is in the starting state
5720f11c7f63SJim Harris  * link down handler is called.
5721f11c7f63SJim Harris  *    - Report the link down condition to the port object
5722f11c7f63SJim Harris  *
5723f11c7f63SJim Harris  * @param[in] controller This is SCIC_SDS_CONTROLLER which receives the
5724f11c7f63SJim Harris  *       link down notification.
5725f11c7f63SJim Harris  * @param[in] port This is SCIC_SDS_PORT with which the phy is associated.
5726f11c7f63SJim Harris  * @param[in] phy This is the SCIC_SDS_PHY which has gone link down.
5727f11c7f63SJim Harris  *
5728f11c7f63SJim Harris  * @return none
5729f11c7f63SJim Harris  */
5730f11c7f63SJim Harris static
scic_sds_controller_starting_state_link_down_handler(SCIC_SDS_CONTROLLER_T * this_controller,SCIC_SDS_PORT_T * port,SCIC_SDS_PHY_T * phy)5731f11c7f63SJim Harris void scic_sds_controller_starting_state_link_down_handler(
5732f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller,
5733f11c7f63SJim Harris    SCIC_SDS_PORT_T       *port,
5734f11c7f63SJim Harris    SCIC_SDS_PHY_T        *phy
5735f11c7f63SJim Harris )
5736f11c7f63SJim Harris {
5737f11c7f63SJim Harris    this_controller->port_agent.link_down_handler(
5738f11c7f63SJim Harris       this_controller, &this_controller->port_agent, port, phy
5739f11c7f63SJim Harris    );
5740f11c7f63SJim Harris    //scic_sds_port_link_down(port, phy);
5741f11c7f63SJim Harris }
5742f11c7f63SJim Harris 
5743f11c7f63SJim Harris //*****************************************************************************
5744f11c7f63SJim Harris //* READY STATE HANDLERS
5745f11c7f63SJim Harris //*****************************************************************************
5746f11c7f63SJim Harris 
5747f11c7f63SJim Harris /**
5748f11c7f63SJim Harris  * This method is called when the SCIC_SDS_CONTROLLER is in the ready state
5749f11c7f63SJim Harris  * stop handler is called.
5750f11c7f63SJim Harris  *    - Start the timeout timer
5751f11c7f63SJim Harris  *    - Transition to SCI_BASE_CONTROLLER_STATE_STOPPING.
5752f11c7f63SJim Harris  *
5753f11c7f63SJim Harris  * @param[in] controller The SCI_BASE_CONTROLLER object which is cast into a
5754f11c7f63SJim Harris  *       SCIC_SDS_CONTROLLER object.
5755f11c7f63SJim Harris  * @param[in] timeout The timeout for when the stop operation should report a
5756f11c7f63SJim Harris  *       failure.
5757f11c7f63SJim Harris  *
5758f11c7f63SJim Harris  * @return SCI_STATUS
5759f11c7f63SJim Harris  * @retval SCI_SUCCESS
5760f11c7f63SJim Harris  */
5761f11c7f63SJim Harris static
scic_sds_controller_ready_state_stop_handler(SCI_BASE_CONTROLLER_T * controller,U32 timeout)5762f11c7f63SJim Harris SCI_STATUS scic_sds_controller_ready_state_stop_handler(
5763f11c7f63SJim Harris    SCI_BASE_CONTROLLER_T *controller,
5764f11c7f63SJim Harris    U32                   timeout
5765f11c7f63SJim Harris )
5766f11c7f63SJim Harris {
5767f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
5768f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
5769f11c7f63SJim Harris 
5770f11c7f63SJim Harris    // See if the user requested to timeout this operation
5771f11c7f63SJim Harris    if (timeout != 0)
5772f11c7f63SJim Harris       scic_cb_timer_start(controller, this_controller->timeout_timer, timeout);
5773f11c7f63SJim Harris 
5774f11c7f63SJim Harris    sci_base_state_machine_change_state(
5775f11c7f63SJim Harris       scic_sds_controller_get_base_state_machine(this_controller),
5776f11c7f63SJim Harris       SCI_BASE_CONTROLLER_STATE_STOPPING
5777f11c7f63SJim Harris    );
5778f11c7f63SJim Harris 
5779f11c7f63SJim Harris    return SCI_SUCCESS;
5780f11c7f63SJim Harris }
5781f11c7f63SJim Harris 
5782f11c7f63SJim Harris /**
5783f11c7f63SJim Harris  * This method is called when the SCIC_SDS_CONTROLLER is in the ready state
5784f11c7f63SJim Harris  * and the start io handler is called.
5785f11c7f63SJim Harris  *    - Start the io request on the remote device
5786f11c7f63SJim Harris  *    - if successful
5787f11c7f63SJim Harris  *       - assign the io_request to the io_request_table
5788f11c7f63SJim Harris  *       - post the request to the hardware
5789f11c7f63SJim Harris  *
5790f11c7f63SJim Harris  * @param[in] controller This is SCI_BASE_CONTROLLER object which is cast
5791f11c7f63SJim Harris  *       into a SCIC_SDS_CONTROLLER object.
5792f11c7f63SJim Harris  * @param[in] remote_device This is SCI_BASE_REMOTE_DEVICE which is cast to a
5793f11c7f63SJim Harris  *       SCIC_SDS_REMOTE_DEVICE object.
5794f11c7f63SJim Harris  * @param[in] io_request This is the SCI_BASE_REQUEST which is cast to a
5795f11c7f63SJim Harris  *       SCIC_SDS_IO_REQUEST object.
5796f11c7f63SJim Harris  * @param[in] io_tag This is the IO tag to be assigned to the IO request or
5797f11c7f63SJim Harris  *       SCI_CONTROLLER_INVALID_IO_TAG.
5798f11c7f63SJim Harris  *
5799f11c7f63SJim Harris  * @return SCI_STATUS
5800f11c7f63SJim Harris  * @retval SCI_SUCCESS if the start io operation succeeds
5801f11c7f63SJim Harris  * @retval SCI_FAILURE_INSUFFICIENT_RESOURCES if the IO tag could not be
5802f11c7f63SJim Harris  *         allocated for the io request.
5803f11c7f63SJim Harris  * @retval SCI_FAILURE_INVALID_STATE if one or more objects are not in a valid
5804f11c7f63SJim Harris  *         state to accept io requests.
5805f11c7f63SJim Harris  *
5806f11c7f63SJim Harris  * @todo How does the io_tag parameter get assigned to the io request?
5807f11c7f63SJim Harris  */
5808f11c7f63SJim Harris static
scic_sds_controller_ready_state_start_io_handler(SCI_BASE_CONTROLLER_T * controller,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request,U16 io_tag)5809f11c7f63SJim Harris SCI_STATUS scic_sds_controller_ready_state_start_io_handler(
5810f11c7f63SJim Harris    SCI_BASE_CONTROLLER_T    *controller,
5811f11c7f63SJim Harris    SCI_BASE_REMOTE_DEVICE_T *remote_device,
5812f11c7f63SJim Harris    SCI_BASE_REQUEST_T       *io_request,
5813f11c7f63SJim Harris    U16                       io_tag
5814f11c7f63SJim Harris )
5815f11c7f63SJim Harris {
5816f11c7f63SJim Harris    SCI_STATUS status;
5817f11c7f63SJim Harris 
5818f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T    *this_controller;
5819f11c7f63SJim Harris    SCIC_SDS_REQUEST_T       *the_request;
5820f11c7f63SJim Harris    SCIC_SDS_REMOTE_DEVICE_T *the_device;
5821f11c7f63SJim Harris 
5822f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
5823f11c7f63SJim Harris    the_request = (SCIC_SDS_REQUEST_T *)io_request;
5824f11c7f63SJim Harris    the_device = (SCIC_SDS_REMOTE_DEVICE_T *)remote_device;
5825f11c7f63SJim Harris 
5826f11c7f63SJim Harris    status = scic_sds_remote_device_start_io(this_controller, the_device, the_request);
5827f11c7f63SJim Harris 
5828f11c7f63SJim Harris    if (status == SCI_SUCCESS)
5829f11c7f63SJim Harris    {
5830f11c7f63SJim Harris       this_controller->io_request_table[
5831f11c7f63SJim Harris             scic_sds_io_tag_get_index(the_request->io_tag)] = the_request;
5832f11c7f63SJim Harris 
5833f11c7f63SJim Harris       scic_sds_controller_post_request(
5834f11c7f63SJim Harris          this_controller,
5835f11c7f63SJim Harris          scic_sds_request_get_post_context(the_request)
5836f11c7f63SJim Harris       );
5837f11c7f63SJim Harris    }
5838f11c7f63SJim Harris 
5839f11c7f63SJim Harris    return status;
5840f11c7f63SJim Harris }
5841f11c7f63SJim Harris 
5842f11c7f63SJim Harris /**
5843f11c7f63SJim Harris  * This method is called when the SCIC_SDS_CONTROLLER is in the ready state
5844f11c7f63SJim Harris  * and the complete io handler is called.
5845f11c7f63SJim Harris  *    - Complete the io request on the remote device
5846f11c7f63SJim Harris  *    - if successful
5847f11c7f63SJim Harris  *       - remove the io_request to the io_request_table
5848f11c7f63SJim Harris  *
5849f11c7f63SJim Harris  * @param[in] controller This is SCI_BASE_CONTROLLER object which is cast
5850f11c7f63SJim Harris  *       into a SCIC_SDS_CONTROLLER object.
5851f11c7f63SJim Harris  * @param[in] remote_device This is SCI_BASE_REMOTE_DEVICE which is cast to a
5852f11c7f63SJim Harris  *       SCIC_SDS_REMOTE_DEVICE object.
5853f11c7f63SJim Harris  * @param[in] io_request This is the SCI_BASE_REQUEST which is cast to a
5854f11c7f63SJim Harris  *       SCIC_SDS_IO_REQUEST object.
5855f11c7f63SJim Harris  *
5856f11c7f63SJim Harris  * @return SCI_STATUS
5857f11c7f63SJim Harris  * @retval SCI_SUCCESS if the start io operation succeeds
5858f11c7f63SJim Harris  * @retval SCI_FAILURE_INVALID_STATE if one or more objects are not in a valid
5859f11c7f63SJim Harris  *         state to accept io requests.
5860f11c7f63SJim Harris  */
5861f11c7f63SJim Harris static
scic_sds_controller_ready_state_complete_io_handler(SCI_BASE_CONTROLLER_T * controller,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request)5862f11c7f63SJim Harris SCI_STATUS scic_sds_controller_ready_state_complete_io_handler(
5863f11c7f63SJim Harris    SCI_BASE_CONTROLLER_T    *controller,
5864f11c7f63SJim Harris    SCI_BASE_REMOTE_DEVICE_T *remote_device,
5865f11c7f63SJim Harris    SCI_BASE_REQUEST_T       *io_request
5866f11c7f63SJim Harris )
5867f11c7f63SJim Harris {
5868f11c7f63SJim Harris    U16        index;
5869f11c7f63SJim Harris    SCI_STATUS status;
5870f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T    *this_controller;
5871f11c7f63SJim Harris    SCIC_SDS_REQUEST_T       *the_request;
5872f11c7f63SJim Harris    SCIC_SDS_REMOTE_DEVICE_T *the_device;
5873f11c7f63SJim Harris 
5874f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
5875f11c7f63SJim Harris    the_request = (SCIC_SDS_REQUEST_T *)io_request;
5876f11c7f63SJim Harris    the_device = (SCIC_SDS_REMOTE_DEVICE_T *)remote_device;
5877f11c7f63SJim Harris 
5878f11c7f63SJim Harris    status = scic_sds_remote_device_complete_io(
5879f11c7f63SJim Harris                   this_controller, the_device, the_request);
5880f11c7f63SJim Harris 
5881f11c7f63SJim Harris    if (status == SCI_SUCCESS)
5882f11c7f63SJim Harris    {
5883f11c7f63SJim Harris       index = scic_sds_io_tag_get_index(the_request->io_tag);
5884f11c7f63SJim Harris       this_controller->io_request_table[index] = SCI_INVALID_HANDLE;
5885f11c7f63SJim Harris    }
5886f11c7f63SJim Harris 
5887f11c7f63SJim Harris    return status;
5888f11c7f63SJim Harris }
5889f11c7f63SJim Harris 
5890f11c7f63SJim Harris /**
5891f11c7f63SJim Harris  * This method is called when the SCIC_SDS_CONTROLLER is in the ready state
5892f11c7f63SJim Harris  * and the continue io handler is called.
5893f11c7f63SJim Harris  *
5894f11c7f63SJim Harris  * @param[in] controller This is SCI_BASE_CONTROLLER object which is cast
5895f11c7f63SJim Harris  *       into a SCIC_SDS_CONTROLLER object.
5896f11c7f63SJim Harris  * @param[in] remote_device This is SCI_BASE_REMOTE_DEVICE which is cast to a
5897f11c7f63SJim Harris  *       SCIC_SDS_REMOTE_DEVICE object.
5898f11c7f63SJim Harris  * @param[in] io_request This is the SCI_BASE_REQUEST which is cast to a
5899f11c7f63SJim Harris  *       SCIC_SDS_IO_REQUEST object.
5900f11c7f63SJim Harris  *
5901f11c7f63SJim Harris  * @return SCI_STATUS
5902f11c7f63SJim Harris  */
5903f11c7f63SJim Harris static
scic_sds_controller_ready_state_continue_io_handler(SCI_BASE_CONTROLLER_T * controller,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request)5904f11c7f63SJim Harris SCI_STATUS scic_sds_controller_ready_state_continue_io_handler(
5905f11c7f63SJim Harris    SCI_BASE_CONTROLLER_T    *controller,
5906f11c7f63SJim Harris    SCI_BASE_REMOTE_DEVICE_T *remote_device,
5907f11c7f63SJim Harris    SCI_BASE_REQUEST_T       *io_request
5908f11c7f63SJim Harris )
5909f11c7f63SJim Harris {
5910f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
5911f11c7f63SJim Harris    SCIC_SDS_REQUEST_T    *the_request;
5912f11c7f63SJim Harris 
5913f11c7f63SJim Harris    the_request     = (SCIC_SDS_REQUEST_T *)io_request;
5914f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
5915f11c7f63SJim Harris 
5916f11c7f63SJim Harris    this_controller->io_request_table[
5917f11c7f63SJim Harris       scic_sds_io_tag_get_index(the_request->io_tag)] = the_request;
5918f11c7f63SJim Harris 
5919f11c7f63SJim Harris    scic_sds_controller_post_request(
5920f11c7f63SJim Harris       this_controller,
5921f11c7f63SJim Harris       scic_sds_request_get_post_context(the_request)
5922f11c7f63SJim Harris    );
5923f11c7f63SJim Harris 
5924f11c7f63SJim Harris    return SCI_SUCCESS;
5925f11c7f63SJim Harris }
5926f11c7f63SJim Harris 
5927f11c7f63SJim Harris /**
5928f11c7f63SJim Harris  * This method is called when the SCIC_SDS_CONTROLLER is in the ready state
5929f11c7f63SJim Harris  * and the start task handler is called.
5930f11c7f63SJim Harris  *    - The remote device is requested to start the task request
5931f11c7f63SJim Harris  *    - if successful
5932f11c7f63SJim Harris  *       - assign the task to the io_request_table
5933f11c7f63SJim Harris  *       - post the request to the SCU hardware
5934f11c7f63SJim Harris  *
5935f11c7f63SJim Harris  * @param[in] controller This is SCI_BASE_CONTROLLER object which is cast
5936f11c7f63SJim Harris  *       into a SCIC_SDS_CONTROLLER object.
5937f11c7f63SJim Harris  * @param[in] remote_device This is SCI_BASE_REMOTE_DEVICE which is cast to a
5938f11c7f63SJim Harris  *       SCIC_SDS_REMOTE_DEVICE object.
5939f11c7f63SJim Harris  * @param[in] io_request This is the SCI_BASE_REQUEST which is cast to a
5940f11c7f63SJim Harris  *       SCIC_SDS_IO_REQUEST object.
5941f11c7f63SJim Harris  * @param[in] task_tag This is the task tag to be assigned to the task request
5942f11c7f63SJim Harris  *       or SCI_CONTROLLER_INVALID_IO_TAG.
5943f11c7f63SJim Harris  *
5944f11c7f63SJim Harris  * @return SCI_STATUS
5945f11c7f63SJim Harris  * @retval SCI_SUCCESS if the start io operation succeeds
5946f11c7f63SJim Harris  * @retval SCI_FAILURE_INSUFFICIENT_RESOURCES if the IO tag could not be
5947f11c7f63SJim Harris  *         allocated for the io request.
5948f11c7f63SJim Harris  * @retval SCI_FAILURE_INVALID_STATE if one or more objects are not in a valid
5949f11c7f63SJim Harris  *         state to accept io requests.
5950f11c7f63SJim Harris  *
5951f11c7f63SJim Harris  * @todo How does the io tag get assigned in this code path?
5952f11c7f63SJim Harris  */
5953f11c7f63SJim Harris static
scic_sds_controller_ready_state_start_task_handler(SCI_BASE_CONTROLLER_T * controller,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request,U16 task_tag)5954f11c7f63SJim Harris SCI_STATUS scic_sds_controller_ready_state_start_task_handler(
5955f11c7f63SJim Harris    SCI_BASE_CONTROLLER_T    *controller,
5956f11c7f63SJim Harris    SCI_BASE_REMOTE_DEVICE_T *remote_device,
5957f11c7f63SJim Harris    SCI_BASE_REQUEST_T       *io_request,
5958f11c7f63SJim Harris    U16                       task_tag
5959f11c7f63SJim Harris )
5960f11c7f63SJim Harris {
5961f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T    *this_controller = (SCIC_SDS_CONTROLLER_T *)
5962f11c7f63SJim Harris                                                controller;
5963f11c7f63SJim Harris    SCIC_SDS_REQUEST_T       *the_request     = (SCIC_SDS_REQUEST_T *)
5964f11c7f63SJim Harris                                                io_request;
5965f11c7f63SJim Harris    SCIC_SDS_REMOTE_DEVICE_T *the_device      = (SCIC_SDS_REMOTE_DEVICE_T *)
5966f11c7f63SJim Harris                                                remote_device;
5967f11c7f63SJim Harris    SCI_STATUS                status;
5968f11c7f63SJim Harris 
5969f11c7f63SJim Harris    status = scic_sds_remote_device_start_task(
5970f11c7f63SJim Harris                this_controller, the_device, the_request
5971f11c7f63SJim Harris             );
5972f11c7f63SJim Harris 
5973f11c7f63SJim Harris    if (status == SCI_SUCCESS)
5974f11c7f63SJim Harris    {
5975f11c7f63SJim Harris       this_controller->io_request_table[
5976f11c7f63SJim Harris          scic_sds_io_tag_get_index(the_request->io_tag)] = the_request;
5977f11c7f63SJim Harris 
5978f11c7f63SJim Harris       scic_sds_controller_post_request(
5979f11c7f63SJim Harris          this_controller,
5980f11c7f63SJim Harris          scic_sds_request_get_post_context(the_request)
5981f11c7f63SJim Harris       );
5982f11c7f63SJim Harris    }
5983f11c7f63SJim Harris    else if (status == SCI_FAILURE_RESET_DEVICE_PARTIAL_SUCCESS)
5984f11c7f63SJim Harris    {
5985f11c7f63SJim Harris       this_controller->io_request_table[
5986f11c7f63SJim Harris          scic_sds_io_tag_get_index(the_request->io_tag)] = the_request;
5987f11c7f63SJim Harris 
5988f11c7f63SJim Harris       //We will let framework know this task request started successfully,
5989f11c7f63SJim Harris       //although core is still woring on starting the request (to post tc when
5990f11c7f63SJim Harris       //RNC is resumed.)
5991f11c7f63SJim Harris       status = SCI_SUCCESS;
5992f11c7f63SJim Harris    }
5993f11c7f63SJim Harris    return status;
5994f11c7f63SJim Harris }
5995f11c7f63SJim Harris 
5996f11c7f63SJim Harris /**
5997f11c7f63SJim Harris  * This method is called when the SCIC_SDS_CONTROLLER is in the ready state
5998f11c7f63SJim Harris  * and the terminate request handler is called.
5999f11c7f63SJim Harris  *    - call the io request terminate function
6000f11c7f63SJim Harris  *    - if successful
6001f11c7f63SJim Harris  *       - post the terminate request to the SCU hardware
6002f11c7f63SJim Harris  *
6003f11c7f63SJim Harris  * @param[in] controller This is SCI_BASE_CONTROLLER object which is cast
6004f11c7f63SJim Harris  *       into a SCIC_SDS_CONTROLLER object.
6005f11c7f63SJim Harris  * @param[in] remote_device This is SCI_BASE_REMOTE_DEVICE which is cast to a
6006f11c7f63SJim Harris  *       SCIC_SDS_REMOTE_DEVICE object.
6007f11c7f63SJim Harris  * @param[in] io_request This is the SCI_BASE_REQUEST which is cast to a
6008f11c7f63SJim Harris  *       SCIC_SDS_IO_REQUEST object.
6009f11c7f63SJim Harris  *
6010f11c7f63SJim Harris  * @return SCI_STATUS
6011f11c7f63SJim Harris  * @retval SCI_SUCCESS if the start io operation succeeds
6012f11c7f63SJim Harris  * @retval SCI_FAILURE_INVALID_STATE if one or more objects are not in a valid
6013f11c7f63SJim Harris  *         state to accept io requests.
6014f11c7f63SJim Harris  */
6015f11c7f63SJim Harris static
scic_sds_controller_ready_state_terminate_request_handler(SCI_BASE_CONTROLLER_T * controller,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request)6016f11c7f63SJim Harris SCI_STATUS scic_sds_controller_ready_state_terminate_request_handler(
6017f11c7f63SJim Harris    SCI_BASE_CONTROLLER_T    *controller,
6018f11c7f63SJim Harris    SCI_BASE_REMOTE_DEVICE_T *remote_device,
6019f11c7f63SJim Harris    SCI_BASE_REQUEST_T       *io_request
6020f11c7f63SJim Harris )
6021f11c7f63SJim Harris {
6022f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T    *this_controller = (SCIC_SDS_CONTROLLER_T *)
6023f11c7f63SJim Harris                                                controller;
6024f11c7f63SJim Harris    SCIC_SDS_REQUEST_T       *the_request     = (SCIC_SDS_REQUEST_T *)
6025f11c7f63SJim Harris                                                io_request;
6026f11c7f63SJim Harris    SCI_STATUS                status;
6027f11c7f63SJim Harris 
6028f11c7f63SJim Harris    status = scic_sds_io_request_terminate(the_request);
6029f11c7f63SJim Harris    if (status == SCI_SUCCESS)
6030f11c7f63SJim Harris    {
6031f11c7f63SJim Harris       // Utilize the original post context command and or in the POST_TC_ABORT
6032f11c7f63SJim Harris       // request sub-type.
6033f11c7f63SJim Harris       scic_sds_controller_post_request(
6034f11c7f63SJim Harris          this_controller,
6035f11c7f63SJim Harris          scic_sds_request_get_post_context(the_request)
6036f11c7f63SJim Harris          | SCU_CONTEXT_COMMAND_REQUEST_POST_TC_ABORT
6037f11c7f63SJim Harris       );
6038f11c7f63SJim Harris    }
6039f11c7f63SJim Harris 
6040f11c7f63SJim Harris    return status;
6041f11c7f63SJim Harris }
6042f11c7f63SJim Harris 
6043f11c7f63SJim Harris /**
6044f11c7f63SJim Harris  * This method is called when the SCIC_SDS_CONTROLLER is in the starting state
6045f11c7f63SJim Harris  * link up handler is called.  This method will perform the following:
6046f11c7f63SJim Harris  *    - Stop the phy timer
6047f11c7f63SJim Harris  *    - Start the next phy
6048f11c7f63SJim Harris  *    - Report the link up condition to the port object
6049f11c7f63SJim Harris  *
6050f11c7f63SJim Harris  * @param[in] controller This is SCIC_SDS_CONTROLLER which receives the link up
6051f11c7f63SJim Harris  *       notification.
6052f11c7f63SJim Harris  * @param[in] port This is SCIC_SDS_PORT with which the phy is associated.
6053f11c7f63SJim Harris  * @param[in] phy This is the SCIC_SDS_PHY which has gone link up.
6054f11c7f63SJim Harris  *
6055f11c7f63SJim Harris  * @return none
6056f11c7f63SJim Harris  */
6057f11c7f63SJim Harris static
scic_sds_controller_ready_state_link_up_handler(SCIC_SDS_CONTROLLER_T * this_controller,SCIC_SDS_PORT_T * port,SCIC_SDS_PHY_T * phy)6058f11c7f63SJim Harris void scic_sds_controller_ready_state_link_up_handler(
6059f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller,
6060f11c7f63SJim Harris    SCIC_SDS_PORT_T       *port,
6061f11c7f63SJim Harris    SCIC_SDS_PHY_T        *phy
6062f11c7f63SJim Harris )
6063f11c7f63SJim Harris {
6064f11c7f63SJim Harris    this_controller->port_agent.link_up_handler(
6065f11c7f63SJim Harris       this_controller, &this_controller->port_agent, port, phy
6066f11c7f63SJim Harris    );
6067f11c7f63SJim Harris }
6068f11c7f63SJim Harris 
6069f11c7f63SJim Harris /**
6070f11c7f63SJim Harris  * This method is called when the SCIC_SDS_CONTROLLER is in the starting state
6071f11c7f63SJim Harris  * link down handler is called.
6072f11c7f63SJim Harris  *    - Report the link down condition to the port object
6073f11c7f63SJim Harris  *
6074f11c7f63SJim Harris  * @param[in] controller This is SCIC_SDS_CONTROLLER which receives the
6075f11c7f63SJim Harris  *       link down notification.
6076f11c7f63SJim Harris  * @param[in] port This is SCIC_SDS_PORT with which the phy is associated.
6077f11c7f63SJim Harris  * @param[in] phy This is the SCIC_SDS_PHY which has gone link down.
6078f11c7f63SJim Harris  *
6079f11c7f63SJim Harris  * @return none
6080f11c7f63SJim Harris  */
6081f11c7f63SJim Harris static
scic_sds_controller_ready_state_link_down_handler(SCIC_SDS_CONTROLLER_T * this_controller,SCIC_SDS_PORT_T * port,SCIC_SDS_PHY_T * phy)6082f11c7f63SJim Harris void scic_sds_controller_ready_state_link_down_handler(
6083f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller,
6084f11c7f63SJim Harris    SCIC_SDS_PORT_T       *port,
6085f11c7f63SJim Harris    SCIC_SDS_PHY_T        *phy
6086f11c7f63SJim Harris )
6087f11c7f63SJim Harris {
6088f11c7f63SJim Harris    this_controller->port_agent.link_down_handler(
6089f11c7f63SJim Harris       this_controller, &this_controller->port_agent, port, phy
6090f11c7f63SJim Harris    );
6091f11c7f63SJim Harris }
6092f11c7f63SJim Harris 
6093f11c7f63SJim Harris //*****************************************************************************
6094f11c7f63SJim Harris //* STOPPING STATE HANDLERS
6095f11c7f63SJim Harris //*****************************************************************************
6096f11c7f63SJim Harris 
6097f11c7f63SJim Harris /**
6098f11c7f63SJim Harris  * This method is called when the SCIC_SDS_CONTROLLER is in a stopping state
6099f11c7f63SJim Harris  * and the complete io handler is called.
6100f11c7f63SJim Harris  *    - This function is not yet implemented
6101f11c7f63SJim Harris  *
6102f11c7f63SJim Harris  * @param[in] controller This is SCI_BASE_CONTROLLER object which is cast
6103f11c7f63SJim Harris  *       into a SCIC_SDS_CONTROLLER object.
6104f11c7f63SJim Harris  * @param[in] remote_device This is SCI_BASE_REMOTE_DEVICE which is cast to a
6105f11c7f63SJim Harris  *       SCIC_SDS_REMOTE_DEVICE object.
6106f11c7f63SJim Harris  * @param[in] io_request This is the SCI_BASE_REQUEST which is cast to a
6107f11c7f63SJim Harris  *       SCIC_SDS_IO_REQUEST object.
6108f11c7f63SJim Harris  *
6109f11c7f63SJim Harris  * @return SCI_STATUS
6110f11c7f63SJim Harris  * @retval SCI_FAILURE
6111f11c7f63SJim Harris  */
6112f11c7f63SJim Harris static
scic_sds_controller_stopping_state_complete_io_handler(SCI_BASE_CONTROLLER_T * controller,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request)6113f11c7f63SJim Harris SCI_STATUS scic_sds_controller_stopping_state_complete_io_handler(
6114f11c7f63SJim Harris    SCI_BASE_CONTROLLER_T    *controller,
6115f11c7f63SJim Harris    SCI_BASE_REMOTE_DEVICE_T *remote_device,
6116f11c7f63SJim Harris    SCI_BASE_REQUEST_T       *io_request
6117f11c7f63SJim Harris )
6118f11c7f63SJim Harris {
6119f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
6120f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
6121f11c7f63SJim Harris 
6122f11c7f63SJim Harris    /// @todo Implement this function
6123f11c7f63SJim Harris    return SCI_FAILURE;
6124f11c7f63SJim Harris }
6125f11c7f63SJim Harris 
6126f11c7f63SJim Harris /**
6127f11c7f63SJim Harris  * This method is called when the SCIC_SDS_CONTROLLER is in a stopping state
6128f11c7f63SJim Harris  * and the a remote device has stopped.
6129f11c7f63SJim Harris  *
6130f11c7f63SJim Harris  * @param[in] controller This is SCI_BASE_CONTROLLER object which is cast
6131f11c7f63SJim Harris  *       into a SCIC_SDS_CONTROLLER object.
6132f11c7f63SJim Harris  * @param[in] remote_device This is SCI_BASE_REMOTE_DEVICE which is cast to a
6133f11c7f63SJim Harris  *       SCIC_SDS_REMOTE_DEVICE object.
6134f11c7f63SJim Harris  *
6135f11c7f63SJim Harris  * @return none
6136f11c7f63SJim Harris  */
6137f11c7f63SJim Harris static
scic_sds_controller_stopping_state_device_stopped_handler(SCIC_SDS_CONTROLLER_T * controller,SCIC_SDS_REMOTE_DEVICE_T * remote_device)6138f11c7f63SJim Harris void scic_sds_controller_stopping_state_device_stopped_handler(
6139f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T    * controller,
6140f11c7f63SJim Harris    SCIC_SDS_REMOTE_DEVICE_T * remote_device
6141f11c7f63SJim Harris )
6142f11c7f63SJim Harris {
6143f11c7f63SJim Harris    if (!scic_sds_controller_has_remote_devices_stopping(controller))
6144f11c7f63SJim Harris    {
6145f11c7f63SJim Harris       sci_base_state_machine_change_state(
6146f11c7f63SJim Harris          &controller->parent.state_machine,
6147f11c7f63SJim Harris          SCI_BASE_CONTROLLER_STATE_STOPPED
6148f11c7f63SJim Harris       );
6149f11c7f63SJim Harris    }
6150f11c7f63SJim Harris }
6151f11c7f63SJim Harris 
6152f11c7f63SJim Harris //*****************************************************************************
6153f11c7f63SJim Harris //* STOPPED STATE HANDLERS
6154f11c7f63SJim Harris //*****************************************************************************
6155f11c7f63SJim Harris 
6156f11c7f63SJim Harris //*****************************************************************************
6157f11c7f63SJim Harris //* FAILED STATE HANDLERS
6158f11c7f63SJim Harris //*****************************************************************************
6159f11c7f63SJim Harris 
6160f11c7f63SJim Harris /**
6161f11c7f63SJim Harris  * This method is called when the SCIC_SDS_CONTROLLER failed state start
6162f11c7f63SJim Harris  * io/task handler is in place.
6163f11c7f63SJim Harris  *    - Issue a warning message
6164f11c7f63SJim Harris  *
6165f11c7f63SJim Harris  * @param[in] controller This is SCI_BASE_CONTROLLER object which is cast
6166f11c7f63SJim Harris  *       into a SCIC_SDS_CONTROLLER object.
6167f11c7f63SJim Harris  * @param[in] remote_device This is SCI_BASE_REMOTE_DEVICE which, if it was
6168f11c7f63SJim Harris  *       used, would be cast to a SCIC_SDS_REMOTE_DEVICE.
6169f11c7f63SJim Harris  * @param[in] io_request This is the SCI_BASE_REQUEST which, if it was used,
6170f11c7f63SJim Harris  *       would be cast to a SCIC_SDS_IO_REQUEST.
6171f11c7f63SJim Harris  * @param[in] io_tag This is the IO tag to be assigned to the IO request or
6172f11c7f63SJim Harris  *       SCI_CONTROLLER_INVALID_IO_TAG.
6173f11c7f63SJim Harris  *
6174f11c7f63SJim Harris  * @return SCI_FAILURE
6175f11c7f63SJim Harris  * @retval SCI_FAILURE
6176f11c7f63SJim Harris  */
6177f11c7f63SJim Harris static
scic_sds_controller_failed_state_start_operation_handler(SCI_BASE_CONTROLLER_T * controller,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request,U16 io_tag)6178f11c7f63SJim Harris SCI_STATUS scic_sds_controller_failed_state_start_operation_handler(
6179f11c7f63SJim Harris    SCI_BASE_CONTROLLER_T    *controller,
6180f11c7f63SJim Harris    SCI_BASE_REMOTE_DEVICE_T *remote_device,
6181f11c7f63SJim Harris    SCI_BASE_REQUEST_T       *io_request,
6182f11c7f63SJim Harris    U16                       io_tag
6183f11c7f63SJim Harris )
6184f11c7f63SJim Harris {
6185f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
6186f11c7f63SJim Harris    this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
6187f11c7f63SJim Harris 
6188f11c7f63SJim Harris    SCIC_LOG_WARNING((
6189f11c7f63SJim Harris       sci_base_object_get_logger(this_controller),
6190f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
6191f11c7f63SJim Harris       "SCIC Controller requested to start an io/task from failed state %d\n",
6192f11c7f63SJim Harris       sci_base_state_machine_get_state(
6193f11c7f63SJim Harris          scic_sds_controller_get_base_state_machine(this_controller))
6194f11c7f63SJim Harris    ));
6195f11c7f63SJim Harris 
6196f11c7f63SJim Harris    return SCI_FAILURE;
6197f11c7f63SJim Harris }
6198f11c7f63SJim Harris 
6199f11c7f63SJim Harris /**
6200f11c7f63SJim Harris  * This method is called when the SCIC_SDS_CONTROLLER is in the failed state
6201f11c7f63SJim Harris  * reset handler is in place.
6202f11c7f63SJim Harris  *    - Transition to SCI_BASE_CONTROLLER_STATE_RESETTING
6203f11c7f63SJim Harris  *
6204f11c7f63SJim Harris  * @param[in] controller The SCI_BASE_CONTROLLER object which is cast into a
6205f11c7f63SJim Harris  *       SCIC_SDS_CONTROLLER object.
6206f11c7f63SJim Harris  *
6207f11c7f63SJim Harris  * @return SCI_STATUS
6208f11c7f63SJim Harris  * @retval SCI_FAILURE if fatal memory error occurred
6209f11c7f63SJim Harris  */
6210f11c7f63SJim Harris static
scic_sds_controller_failed_state_reset_handler(SCI_BASE_CONTROLLER_T * controller)6211f11c7f63SJim Harris SCI_STATUS scic_sds_controller_failed_state_reset_handler(
6212f11c7f63SJim Harris    SCI_BASE_CONTROLLER_T *controller
6213f11c7f63SJim Harris )
6214f11c7f63SJim Harris {
6215f11c7f63SJim Harris     SCIC_SDS_CONTROLLER_T *this_controller;
6216f11c7f63SJim Harris     this_controller = (SCIC_SDS_CONTROLLER_T *)controller;
6217f11c7f63SJim Harris 
6218f11c7f63SJim Harris     if (this_controller->parent.error == SCI_CONTROLLER_FATAL_MEMORY_ERROR) {
6219f11c7f63SJim Harris         SCIC_LOG_TRACE((
6220f11c7f63SJim Harris            sci_base_object_get_logger(controller),
6221f11c7f63SJim Harris            SCIC_LOG_OBJECT_CONTROLLER,
6222f11c7f63SJim Harris            "scic_sds_controller_resetting_state_enter(0x%x) enter\n not allowed with fatal memory error",
6223f11c7f63SJim Harris            controller
6224f11c7f63SJim Harris         ));
6225f11c7f63SJim Harris 
6226f11c7f63SJim Harris         return SCI_FAILURE;
6227f11c7f63SJim Harris     } else {
6228f11c7f63SJim Harris         return scic_sds_controller_general_reset_handler(controller);
6229f11c7f63SJim Harris     }
6230f11c7f63SJim Harris }
6231f11c7f63SJim Harris 
6232f11c7f63SJim Harris /**
6233f11c7f63SJim Harris  * This method is called when the SCIC_SDS_CONTROLLER is in the failed state
6234f11c7f63SJim Harris  * and the terminate request handler is called.
6235f11c7f63SJim Harris  *    - call the io request terminate function
6236f11c7f63SJim Harris  *    - if successful
6237f11c7f63SJim Harris  *       - post the terminate request to the SCU hardware
6238f11c7f63SJim Harris  *
6239f11c7f63SJim Harris  * @param[in] controller This is SCI_BASE_CONTROLLER object which is cast
6240f11c7f63SJim Harris  *       into a SCIC_SDS_CONTROLLER object.
6241f11c7f63SJim Harris  * @param[in] remote_device This is SCI_BASE_REMOTE_DEVICE which is cast to a
6242f11c7f63SJim Harris  *       SCIC_SDS_REMOTE_DEVICE object.
6243f11c7f63SJim Harris  * @param[in] io_request This is the SCI_BASE_REQUEST which is cast to a
6244f11c7f63SJim Harris  *       SCIC_SDS_IO_REQUEST object.
6245f11c7f63SJim Harris  *
6246f11c7f63SJim Harris  * @return SCI_STATUS
6247f11c7f63SJim Harris  * @retval SCI_SUCCESS if the start io operation succeeds
6248f11c7f63SJim Harris  * @retval SCI_FAILURE_INVALID_STATE if one or more objects are not in a valid
6249f11c7f63SJim Harris  *         state to accept io requests.
6250f11c7f63SJim Harris  */
6251f11c7f63SJim Harris static
scic_sds_controller_failed_state_terminate_request_handler(SCI_BASE_CONTROLLER_T * controller,SCI_BASE_REMOTE_DEVICE_T * remote_device,SCI_BASE_REQUEST_T * io_request)6252f11c7f63SJim Harris SCI_STATUS scic_sds_controller_failed_state_terminate_request_handler(
6253f11c7f63SJim Harris    SCI_BASE_CONTROLLER_T    *controller,
6254f11c7f63SJim Harris    SCI_BASE_REMOTE_DEVICE_T *remote_device,
6255f11c7f63SJim Harris    SCI_BASE_REQUEST_T       *io_request
6256f11c7f63SJim Harris )
6257f11c7f63SJim Harris {
6258f11c7f63SJim Harris    SCIC_SDS_REQUEST_T       *the_request     = (SCIC_SDS_REQUEST_T *)
6259f11c7f63SJim Harris                                                io_request;
6260f11c7f63SJim Harris 
6261f11c7f63SJim Harris    return scic_sds_io_request_terminate(the_request);
6262f11c7f63SJim Harris }
6263f11c7f63SJim Harris 
6264f11c7f63SJim Harris SCIC_SDS_CONTROLLER_STATE_HANDLER_T
6265f11c7f63SJim Harris    scic_sds_controller_state_handler_table[SCI_BASE_CONTROLLER_MAX_STATES] =
6266f11c7f63SJim Harris {
6267f11c7f63SJim Harris    // SCI_BASE_CONTROLLER_STATE_INITIAL
6268f11c7f63SJim Harris    {
6269f11c7f63SJim Harris       {
6270f11c7f63SJim Harris          NULL,
6271f11c7f63SJim Harris          NULL,
6272f11c7f63SJim Harris          NULL,
6273f11c7f63SJim Harris          NULL,
6274f11c7f63SJim Harris          scic_sds_controller_default_start_operation_handler,
6275f11c7f63SJim Harris          scic_sds_controller_default_start_operation_handler,
6276f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6277f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6278f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6279f11c7f63SJim Harris          NULL,
6280f11c7f63SJim Harris          NULL
6281f11c7f63SJim Harris       },
6282f11c7f63SJim Harris       scic_sds_controller_default_request_handler,
6283f11c7f63SJim Harris       NULL,
6284f11c7f63SJim Harris       NULL,
6285f11c7f63SJim Harris       NULL,
6286f11c7f63SJim Harris       NULL
6287f11c7f63SJim Harris    },
6288f11c7f63SJim Harris    // SCI_BASE_CONTROLLER_STATE_RESET
6289f11c7f63SJim Harris    {
6290f11c7f63SJim Harris       {
6291f11c7f63SJim Harris          NULL,
6292f11c7f63SJim Harris          NULL,
6293f11c7f63SJim Harris          NULL,
6294f11c7f63SJim Harris          scic_sds_controller_reset_state_initialize_handler,
6295f11c7f63SJim Harris          scic_sds_controller_default_start_operation_handler,
6296f11c7f63SJim Harris          scic_sds_controller_default_start_operation_handler,
6297f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6298f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6299f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6300f11c7f63SJim Harris          NULL,
6301f11c7f63SJim Harris          NULL
6302f11c7f63SJim Harris       },
6303f11c7f63SJim Harris       scic_sds_controller_default_request_handler,
6304f11c7f63SJim Harris       NULL,
6305f11c7f63SJim Harris       NULL,
6306f11c7f63SJim Harris       NULL,
6307f11c7f63SJim Harris       NULL
6308f11c7f63SJim Harris    },
6309f11c7f63SJim Harris    // SCI_BASE_CONTROLLER_STATE_INITIALIZING
6310f11c7f63SJim Harris    {
6311f11c7f63SJim Harris       {
6312f11c7f63SJim Harris          NULL,
6313f11c7f63SJim Harris          NULL,
6314f11c7f63SJim Harris          NULL,
6315f11c7f63SJim Harris          NULL,
6316f11c7f63SJim Harris          scic_sds_controller_default_start_operation_handler,
6317f11c7f63SJim Harris          scic_sds_controller_default_start_operation_handler,
6318f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6319f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6320f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6321f11c7f63SJim Harris          NULL,
6322f11c7f63SJim Harris          NULL
6323f11c7f63SJim Harris       },
6324f11c7f63SJim Harris       scic_sds_controller_default_request_handler,
6325f11c7f63SJim Harris       NULL,
6326f11c7f63SJim Harris       NULL,
6327f11c7f63SJim Harris       NULL,
6328f11c7f63SJim Harris       NULL
6329f11c7f63SJim Harris    },
6330f11c7f63SJim Harris    // SCI_BASE_CONTROLLER_STATE_INITIALIZED
6331f11c7f63SJim Harris    {
6332f11c7f63SJim Harris       {
6333f11c7f63SJim Harris          scic_sds_controller_initialized_state_start_handler,
6334f11c7f63SJim Harris          NULL,
6335f11c7f63SJim Harris          NULL,
6336f11c7f63SJim Harris          NULL,
6337f11c7f63SJim Harris          scic_sds_controller_default_start_operation_handler,
6338f11c7f63SJim Harris          scic_sds_controller_default_start_operation_handler,
6339f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6340f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6341f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6342f11c7f63SJim Harris          NULL,
6343f11c7f63SJim Harris          NULL
6344f11c7f63SJim Harris       },
6345f11c7f63SJim Harris       scic_sds_controller_default_request_handler,
6346f11c7f63SJim Harris       NULL,
6347f11c7f63SJim Harris       NULL,
6348f11c7f63SJim Harris       NULL,
6349f11c7f63SJim Harris       NULL
6350f11c7f63SJim Harris    },
6351f11c7f63SJim Harris    // SCI_BASE_CONTROLLER_STATE_STARTING
6352f11c7f63SJim Harris    {
6353f11c7f63SJim Harris       {
6354f11c7f63SJim Harris          NULL,
6355f11c7f63SJim Harris          NULL,
6356f11c7f63SJim Harris          NULL,
6357f11c7f63SJim Harris          NULL,
6358f11c7f63SJim Harris          scic_sds_controller_default_start_operation_handler,
6359f11c7f63SJim Harris          scic_sds_controller_default_start_operation_handler,
6360f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6361f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6362f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6363f11c7f63SJim Harris          NULL,
6364f11c7f63SJim Harris          NULL
6365f11c7f63SJim Harris       },
6366f11c7f63SJim Harris       scic_sds_controller_default_request_handler,
6367f11c7f63SJim Harris       scic_sds_controller_starting_state_link_up_handler,
6368f11c7f63SJim Harris       scic_sds_controller_starting_state_link_down_handler,
6369f11c7f63SJim Harris       NULL,
6370f11c7f63SJim Harris       NULL
6371f11c7f63SJim Harris    },
6372f11c7f63SJim Harris    // SCI_BASE_CONTROLLER_STATE_READY
6373f11c7f63SJim Harris    {
6374f11c7f63SJim Harris       {
6375f11c7f63SJim Harris          NULL,
6376f11c7f63SJim Harris          scic_sds_controller_ready_state_stop_handler,
6377f11c7f63SJim Harris          scic_sds_controller_general_reset_handler,
6378f11c7f63SJim Harris          NULL,
6379f11c7f63SJim Harris          scic_sds_controller_ready_state_start_io_handler,
6380f11c7f63SJim Harris          scic_sds_controller_default_start_operation_handler,
6381f11c7f63SJim Harris          scic_sds_controller_ready_state_complete_io_handler,
6382f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6383f11c7f63SJim Harris          scic_sds_controller_ready_state_continue_io_handler,
6384f11c7f63SJim Harris          scic_sds_controller_ready_state_start_task_handler,
6385f11c7f63SJim Harris          scic_sds_controller_ready_state_complete_io_handler
6386f11c7f63SJim Harris       },
6387f11c7f63SJim Harris       scic_sds_controller_ready_state_terminate_request_handler,
6388f11c7f63SJim Harris       scic_sds_controller_ready_state_link_up_handler,
6389f11c7f63SJim Harris       scic_sds_controller_ready_state_link_down_handler,
6390f11c7f63SJim Harris       NULL,
6391f11c7f63SJim Harris       NULL
6392f11c7f63SJim Harris    },
6393f11c7f63SJim Harris    // SCI_BASE_CONTROLLER_STATE_RESETTING
6394f11c7f63SJim Harris    {
6395f11c7f63SJim Harris       {
6396f11c7f63SJim Harris          NULL,
6397f11c7f63SJim Harris          NULL,
6398f11c7f63SJim Harris          NULL,
6399f11c7f63SJim Harris          NULL,
6400f11c7f63SJim Harris          scic_sds_controller_default_start_operation_handler,
6401f11c7f63SJim Harris          scic_sds_controller_default_start_operation_handler,
6402f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6403f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6404f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6405f11c7f63SJim Harris          NULL,
6406f11c7f63SJim Harris          NULL
6407f11c7f63SJim Harris       },
6408f11c7f63SJim Harris       scic_sds_controller_default_request_handler,
6409f11c7f63SJim Harris       NULL,
6410f11c7f63SJim Harris       NULL,
6411f11c7f63SJim Harris       NULL,
6412f11c7f63SJim Harris       NULL
6413f11c7f63SJim Harris    },
6414f11c7f63SJim Harris    // SCI_BASE_CONTROLLER_STATE_STOPPING
6415f11c7f63SJim Harris    {
6416f11c7f63SJim Harris       {
6417f11c7f63SJim Harris          NULL,
6418f11c7f63SJim Harris          NULL,
6419f11c7f63SJim Harris          NULL,
6420f11c7f63SJim Harris          NULL,
6421f11c7f63SJim Harris          scic_sds_controller_default_start_operation_handler,
6422f11c7f63SJim Harris          scic_sds_controller_default_start_operation_handler,
6423f11c7f63SJim Harris          scic_sds_controller_stopping_state_complete_io_handler,
6424f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6425f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6426f11c7f63SJim Harris          NULL,
6427f11c7f63SJim Harris          NULL
6428f11c7f63SJim Harris       },
6429f11c7f63SJim Harris       scic_sds_controller_default_request_handler,
6430f11c7f63SJim Harris       NULL,
6431f11c7f63SJim Harris       NULL,
6432f11c7f63SJim Harris       NULL,
6433f11c7f63SJim Harris       scic_sds_controller_stopping_state_device_stopped_handler
6434f11c7f63SJim Harris    },
6435f11c7f63SJim Harris    // SCI_BASE_CONTROLLER_STATE_STOPPED
6436f11c7f63SJim Harris    {
6437f11c7f63SJim Harris       {
6438f11c7f63SJim Harris          NULL,
6439f11c7f63SJim Harris          NULL,
6440f11c7f63SJim Harris          scic_sds_controller_failed_state_reset_handler,
6441f11c7f63SJim Harris          NULL,
6442f11c7f63SJim Harris          scic_sds_controller_default_start_operation_handler,
6443f11c7f63SJim Harris          scic_sds_controller_default_start_operation_handler,
6444f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6445f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6446f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6447f11c7f63SJim Harris          NULL,
6448f11c7f63SJim Harris          NULL
6449f11c7f63SJim Harris       },
6450f11c7f63SJim Harris       scic_sds_controller_default_request_handler,
6451f11c7f63SJim Harris       NULL,
6452f11c7f63SJim Harris       NULL,
6453f11c7f63SJim Harris       NULL,
6454f11c7f63SJim Harris       NULL
6455f11c7f63SJim Harris    },
6456f11c7f63SJim Harris    // SCI_BASE_CONTROLLER_STATE_FAILED
6457f11c7f63SJim Harris    {
6458f11c7f63SJim Harris       {
6459f11c7f63SJim Harris          NULL,
6460f11c7f63SJim Harris          NULL,
6461f11c7f63SJim Harris          scic_sds_controller_general_reset_handler,
6462f11c7f63SJim Harris          NULL,
6463f11c7f63SJim Harris          scic_sds_controller_failed_state_start_operation_handler,
6464f11c7f63SJim Harris          scic_sds_controller_failed_state_start_operation_handler,
6465f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6466f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6467f11c7f63SJim Harris          scic_sds_controller_default_request_handler,
6468f11c7f63SJim Harris          NULL,
6469f11c7f63SJim Harris          NULL
6470f11c7f63SJim Harris       },
6471f11c7f63SJim Harris       scic_sds_controller_failed_state_terminate_request_handler,
6472f11c7f63SJim Harris       NULL,
6473f11c7f63SJim Harris       NULL,
6474f11c7f63SJim Harris       NULL
6475f11c7f63SJim Harris    }
6476f11c7f63SJim Harris };
6477f11c7f63SJim Harris 
6478f11c7f63SJim Harris /**
6479f11c7f63SJim Harris  * This method implements the actions taken by the SCIC_SDS_CONTROLLER on
6480f11c7f63SJim Harris  * entry to the SCI_BASE_CONTROLLER_STATE_INITIAL.
6481f11c7f63SJim Harris  *    - Set the state handlers to the controllers initial state.
6482f11c7f63SJim Harris  *
6483f11c7f63SJim Harris  * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
6484f11c7f63SJim Harris  *       SCIC_SDS_CONTROLLER object.
6485f11c7f63SJim Harris  *
6486f11c7f63SJim Harris  * @return none
6487f11c7f63SJim Harris  *
6488f11c7f63SJim Harris  * @todo This function should initialze the controller object.
6489f11c7f63SJim Harris  */
6490f11c7f63SJim Harris static
scic_sds_controller_initial_state_enter(SCI_BASE_OBJECT_T * object)6491f11c7f63SJim Harris void scic_sds_controller_initial_state_enter(
6492f11c7f63SJim Harris    SCI_BASE_OBJECT_T *object
6493f11c7f63SJim Harris )
6494f11c7f63SJim Harris {
6495f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
6496f11c7f63SJim Harris    this_controller= (SCIC_SDS_CONTROLLER_T *)object;
6497f11c7f63SJim Harris 
6498f11c7f63SJim Harris    scic_sds_controller_set_base_state_handlers(
6499f11c7f63SJim Harris       this_controller, SCI_BASE_CONTROLLER_STATE_INITIAL);
6500f11c7f63SJim Harris 
6501f11c7f63SJim Harris    sci_base_state_machine_change_state(
6502f11c7f63SJim Harris       &this_controller->parent.state_machine, SCI_BASE_CONTROLLER_STATE_RESET);
6503f11c7f63SJim Harris }
6504f11c7f63SJim Harris 
6505f11c7f63SJim Harris /**
6506f11c7f63SJim Harris  * This method implements the actions taken by the SCIC_SDS_CONTROLLER on
6507f11c7f63SJim Harris  * entry to the SCI_BASE_CONTROLLER_STATE_RESET.
6508f11c7f63SJim Harris  *    - Set the state handlers to the controllers reset state.
6509f11c7f63SJim Harris  *
6510f11c7f63SJim Harris  * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
6511f11c7f63SJim Harris  *       SCIC_SDS_CONTROLLER object.
6512f11c7f63SJim Harris  *
6513f11c7f63SJim Harris  * @return none
6514f11c7f63SJim Harris  */
6515f11c7f63SJim Harris static
scic_sds_controller_reset_state_enter(SCI_BASE_OBJECT_T * object)6516f11c7f63SJim Harris void scic_sds_controller_reset_state_enter(
6517f11c7f63SJim Harris    SCI_BASE_OBJECT_T *object
6518f11c7f63SJim Harris )
6519f11c7f63SJim Harris {
6520f11c7f63SJim Harris    U8 index;
6521f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
6522f11c7f63SJim Harris    this_controller= (SCIC_SDS_CONTROLLER_T *)object;
6523f11c7f63SJim Harris 
6524f11c7f63SJim Harris    scic_sds_controller_set_base_state_handlers(
6525f11c7f63SJim Harris       this_controller, SCI_BASE_CONTROLLER_STATE_RESET);
6526f11c7f63SJim Harris 
6527f11c7f63SJim Harris    scic_sds_port_configuration_agent_construct(&this_controller->port_agent);
6528f11c7f63SJim Harris 
6529f11c7f63SJim Harris    // Construct the ports for this controller
6530f11c7f63SJim Harris    for (index = 0; index < (SCI_MAX_PORTS + 1); index++)
6531f11c7f63SJim Harris    {
6532f11c7f63SJim Harris       scic_sds_port_construct(
6533f11c7f63SJim Harris          &this_controller->port_table[index],
6534f11c7f63SJim Harris          (index == SCI_MAX_PORTS) ? SCIC_SDS_DUMMY_PORT : index,
6535f11c7f63SJim Harris          this_controller
6536f11c7f63SJim Harris       );
6537f11c7f63SJim Harris    }
6538f11c7f63SJim Harris 
6539f11c7f63SJim Harris    // Construct the phys for this controller
6540f11c7f63SJim Harris    for (index = 0; index < SCI_MAX_PHYS; index++)
6541f11c7f63SJim Harris    {
6542f11c7f63SJim Harris       // Add all the PHYs to the dummy port
6543f11c7f63SJim Harris       scic_sds_phy_construct(
6544f11c7f63SJim Harris          &this_controller->phy_table[index],
6545f11c7f63SJim Harris          &this_controller->port_table[SCI_MAX_PORTS],
6546f11c7f63SJim Harris          index
6547f11c7f63SJim Harris       );
6548f11c7f63SJim Harris    }
6549f11c7f63SJim Harris 
6550f11c7f63SJim Harris    this_controller->invalid_phy_mask = 0;
6551f11c7f63SJim Harris 
6552f11c7f63SJim Harris    // Set the default maximum values
6553f11c7f63SJim Harris    this_controller->completion_event_entries      = SCU_EVENT_COUNT;
6554f11c7f63SJim Harris    this_controller->completion_queue_entries      = SCU_COMPLETION_QUEUE_COUNT;
6555f11c7f63SJim Harris    this_controller->remote_node_entries           = SCI_MAX_REMOTE_DEVICES;
6556f11c7f63SJim Harris    this_controller->logical_port_entries          = SCI_MAX_PORTS;
6557f11c7f63SJim Harris    this_controller->task_context_entries          = SCU_IO_REQUEST_COUNT;
6558f11c7f63SJim Harris    this_controller->uf_control.buffers.count      = SCU_UNSOLICITED_FRAME_COUNT;
6559f11c7f63SJim Harris    this_controller->uf_control.address_table.count= SCU_UNSOLICITED_FRAME_COUNT;
6560f11c7f63SJim Harris 
6561f11c7f63SJim Harris    // Initialize the User and OEM parameters to default values.
6562f11c7f63SJim Harris    scic_sds_controller_set_default_config_parameters(this_controller);
6563f11c7f63SJim Harris }
6564f11c7f63SJim Harris 
6565f11c7f63SJim Harris /**
6566f11c7f63SJim Harris  * This method implements the actions taken by the SCIC_SDS_CONTROLLER on
6567f11c7f63SJim Harris  * entry to the SCI_BASE_CONTROLLER_STATE_INITIALIZING.
6568f11c7f63SJim Harris  *    - Set the state handlers to the controllers initializing state.
6569f11c7f63SJim Harris  *
6570f11c7f63SJim Harris  * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
6571f11c7f63SJim Harris  *       SCIC_SDS_CONTROLLER object.
6572f11c7f63SJim Harris  *
6573f11c7f63SJim Harris  * @return none
6574f11c7f63SJim Harris  */
6575f11c7f63SJim Harris static
scic_sds_controller_initializing_state_enter(SCI_BASE_OBJECT_T * object)6576f11c7f63SJim Harris void scic_sds_controller_initializing_state_enter(
6577f11c7f63SJim Harris    SCI_BASE_OBJECT_T *object
6578f11c7f63SJim Harris )
6579f11c7f63SJim Harris {
6580f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
6581f11c7f63SJim Harris    this_controller= (SCIC_SDS_CONTROLLER_T *)object;
6582f11c7f63SJim Harris 
6583f11c7f63SJim Harris    scic_sds_controller_set_base_state_handlers(
6584f11c7f63SJim Harris       this_controller, SCI_BASE_CONTROLLER_STATE_INITIALIZING);
6585f11c7f63SJim Harris }
6586f11c7f63SJim Harris 
6587f11c7f63SJim Harris /**
6588f11c7f63SJim Harris  * This method implements the actions taken by the SCIC_SDS_CONTROLLER on
6589f11c7f63SJim Harris  * entry to the SCI_BASE_CONTROLLER_STATE_INITIALIZED.
6590f11c7f63SJim Harris  *    - Set the state handlers to the controllers initialized state.
6591f11c7f63SJim Harris  *
6592f11c7f63SJim Harris  * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
6593f11c7f63SJim Harris  *       SCIC_SDS_CONTROLLER object.
6594f11c7f63SJim Harris  *
6595f11c7f63SJim Harris  * @return none
6596f11c7f63SJim Harris  */
6597f11c7f63SJim Harris static
scic_sds_controller_initialized_state_enter(SCI_BASE_OBJECT_T * object)6598f11c7f63SJim Harris void scic_sds_controller_initialized_state_enter(
6599f11c7f63SJim Harris    SCI_BASE_OBJECT_T *object
6600f11c7f63SJim Harris )
6601f11c7f63SJim Harris {
6602f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
6603f11c7f63SJim Harris    this_controller= (SCIC_SDS_CONTROLLER_T *)object;
6604f11c7f63SJim Harris 
6605f11c7f63SJim Harris    scic_sds_controller_set_base_state_handlers(
6606f11c7f63SJim Harris       this_controller, SCI_BASE_CONTROLLER_STATE_INITIALIZED);
6607f11c7f63SJim Harris }
6608f11c7f63SJim Harris 
6609f11c7f63SJim Harris /**
6610f11c7f63SJim Harris  * This method implements the actions taken by the SCIC_SDS_CONTROLLER on
6611f11c7f63SJim Harris  * entry to the SCI_BASE_CONTROLLER_STATE_STARTING.
6612f11c7f63SJim Harris  *    - Set the state handlers to the controllers starting state.
6613f11c7f63SJim Harris  *
6614f11c7f63SJim Harris  * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
6615f11c7f63SJim Harris  *       SCIC_SDS_CONTROLLER object.
6616f11c7f63SJim Harris  *
6617f11c7f63SJim Harris  * @return none
6618f11c7f63SJim Harris  */
6619f11c7f63SJim Harris static
scic_sds_controller_starting_state_enter(SCI_BASE_OBJECT_T * object)6620f11c7f63SJim Harris void scic_sds_controller_starting_state_enter(
6621f11c7f63SJim Harris    SCI_BASE_OBJECT_T *object
6622f11c7f63SJim Harris )
6623f11c7f63SJim Harris {
6624f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
6625f11c7f63SJim Harris    this_controller= (SCIC_SDS_CONTROLLER_T *)object;
6626f11c7f63SJim Harris 
6627f11c7f63SJim Harris    scic_sds_controller_set_base_state_handlers(
6628f11c7f63SJim Harris       this_controller, SCI_BASE_CONTROLLER_STATE_STARTING);
6629f11c7f63SJim Harris 
6630f11c7f63SJim Harris }
6631f11c7f63SJim Harris 
6632f11c7f63SJim Harris /**
6633f11c7f63SJim Harris  * This method implements the actions taken by the SCIC_SDS_CONTROLLER on exit
6634f11c7f63SJim Harris  * from the SCI_BASE_CONTROLLER_STATE_STARTING.
6635f11c7f63SJim Harris  *    - This function stops the controller starting timeout timer.
6636f11c7f63SJim Harris  *
6637f11c7f63SJim Harris  * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
6638f11c7f63SJim Harris  *       SCIC_SDS_CONTROLLER object.
6639f11c7f63SJim Harris  *
6640f11c7f63SJim Harris  * @return none
6641f11c7f63SJim Harris  */
6642f11c7f63SJim Harris static
scic_sds_controller_starting_state_exit(SCI_BASE_OBJECT_T * object)6643f11c7f63SJim Harris void scic_sds_controller_starting_state_exit(
6644f11c7f63SJim Harris    SCI_BASE_OBJECT_T *object
6645f11c7f63SJim Harris )
6646f11c7f63SJim Harris {
6647f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
6648f11c7f63SJim Harris    this_controller= (SCIC_SDS_CONTROLLER_T *)object;
6649f11c7f63SJim Harris 
6650f11c7f63SJim Harris    scic_cb_timer_stop(object, this_controller->timeout_timer);
6651f11c7f63SJim Harris 
6652f11c7f63SJim Harris    // We are done with this timer since we are exiting the starting
6653f11c7f63SJim Harris    // state so remove it
6654f11c7f63SJim Harris    scic_cb_timer_destroy(
6655f11c7f63SJim Harris       this_controller,
6656f11c7f63SJim Harris       this_controller->phy_startup_timer
6657f11c7f63SJim Harris    );
6658f11c7f63SJim Harris 
6659f11c7f63SJim Harris    this_controller->phy_startup_timer = NULL;
6660f11c7f63SJim Harris }
6661f11c7f63SJim Harris 
6662f11c7f63SJim Harris /**
6663f11c7f63SJim Harris  * This method implements the actions taken by the SCIC_SDS_CONTROLLER on
6664f11c7f63SJim Harris  * entry to the SCI_BASE_CONTROLLER_STATE_READY.
6665f11c7f63SJim Harris  *    - Set the state handlers to the controllers ready state.
6666f11c7f63SJim Harris  *
6667f11c7f63SJim Harris  * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
6668f11c7f63SJim Harris  *       SCIC_SDS_CONTROLLER object.
6669f11c7f63SJim Harris  *
6670f11c7f63SJim Harris  * @return none
6671f11c7f63SJim Harris  */
6672f11c7f63SJim Harris static
scic_sds_controller_ready_state_enter(SCI_BASE_OBJECT_T * object)6673f11c7f63SJim Harris void scic_sds_controller_ready_state_enter(
6674f11c7f63SJim Harris    SCI_BASE_OBJECT_T *object
6675f11c7f63SJim Harris )
6676f11c7f63SJim Harris {
6677f11c7f63SJim Harris    U32 clock_gating_unit_value;
6678f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
6679f11c7f63SJim Harris    this_controller= (SCIC_SDS_CONTROLLER_T *)object;
6680f11c7f63SJim Harris 
6681f11c7f63SJim Harris    scic_sds_controller_set_base_state_handlers(
6682f11c7f63SJim Harris       this_controller, SCI_BASE_CONTROLLER_STATE_READY);
6683f11c7f63SJim Harris 
6684f11c7f63SJim Harris    /**
6685f11c7f63SJim Harris     * enable clock gating for power control of the scu unit
6686f11c7f63SJim Harris     */
6687f11c7f63SJim Harris    clock_gating_unit_value = SMU_CGUCR_READ(this_controller);
6688f11c7f63SJim Harris 
6689f11c7f63SJim Harris    clock_gating_unit_value &= ~( SMU_CGUCR_GEN_BIT(REGCLK_ENABLE)
6690f11c7f63SJim Harris                                | SMU_CGUCR_GEN_BIT(TXCLK_ENABLE)
6691f11c7f63SJim Harris                                | SMU_CGUCR_GEN_BIT(XCLK_ENABLE) );
6692f11c7f63SJim Harris    clock_gating_unit_value |= SMU_CGUCR_GEN_BIT(IDLE_ENABLE);
6693f11c7f63SJim Harris 
6694f11c7f63SJim Harris    SMU_CGUCR_WRITE(this_controller, clock_gating_unit_value);
6695f11c7f63SJim Harris 
6696f11c7f63SJim Harris    //set the default interrupt coalescence number and timeout value.
6697f11c7f63SJim Harris    scic_controller_set_interrupt_coalescence(
6698f11c7f63SJim Harris       this_controller, 0x10, 250);
6699f11c7f63SJim Harris }
6700f11c7f63SJim Harris 
6701f11c7f63SJim Harris /**
6702f11c7f63SJim Harris  * This method implements the actions taken by the SCIC_SDS_CONTROLLER on exit
6703f11c7f63SJim Harris  * from the SCI_BASE_CONTROLLER_STATE_READY.
6704f11c7f63SJim Harris  *    - This function does nothing.
6705f11c7f63SJim Harris  *
6706f11c7f63SJim Harris  * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
6707f11c7f63SJim Harris  *       SCIC_SDS_CONTROLLER object.
6708f11c7f63SJim Harris  *
6709f11c7f63SJim Harris  * @return none
6710f11c7f63SJim Harris  */
6711f11c7f63SJim Harris static
scic_sds_controller_ready_state_exit(SCI_BASE_OBJECT_T * object)6712f11c7f63SJim Harris void scic_sds_controller_ready_state_exit(
6713f11c7f63SJim Harris    SCI_BASE_OBJECT_T *object
6714f11c7f63SJim Harris )
6715f11c7f63SJim Harris {
6716f11c7f63SJim Harris    U32 clock_gating_unit_value;
6717f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
6718f11c7f63SJim Harris    this_controller= (SCIC_SDS_CONTROLLER_T *)object;
6719f11c7f63SJim Harris 
6720f11c7f63SJim Harris    /**
6721f11c7f63SJim Harris     * restore clock gating for power control of the scu unit
6722f11c7f63SJim Harris     */
6723f11c7f63SJim Harris    clock_gating_unit_value = SMU_CGUCR_READ(this_controller);
6724f11c7f63SJim Harris 
6725f11c7f63SJim Harris    clock_gating_unit_value &= ~SMU_CGUCR_GEN_BIT(IDLE_ENABLE);
6726f11c7f63SJim Harris    clock_gating_unit_value |= ( SMU_CGUCR_GEN_BIT(REGCLK_ENABLE)
6727f11c7f63SJim Harris                               | SMU_CGUCR_GEN_BIT(TXCLK_ENABLE)
6728f11c7f63SJim Harris                               | SMU_CGUCR_GEN_BIT(XCLK_ENABLE) );
6729f11c7f63SJim Harris 
6730f11c7f63SJim Harris    SMU_CGUCR_WRITE(this_controller, clock_gating_unit_value);
6731f11c7f63SJim Harris 
6732f11c7f63SJim Harris    //disable interrupt coalescence.
6733f11c7f63SJim Harris    scic_controller_set_interrupt_coalescence(this_controller, 0, 0);
6734f11c7f63SJim Harris }
6735f11c7f63SJim Harris 
6736f11c7f63SJim Harris /**
6737f11c7f63SJim Harris  * This method implements the actions taken by the SCIC_SDS_CONTROLLER on
6738f11c7f63SJim Harris  * entry to the SCI_BASE_CONTROLLER_STATE_READY.
6739f11c7f63SJim Harris  *    - Set the state handlers to the controllers ready state.
6740f11c7f63SJim Harris  *    - Stop all of the remote devices on this controller
6741f11c7f63SJim Harris  *    - Stop the ports on this controller
6742f11c7f63SJim Harris  *    - Stop the phys on this controller
6743f11c7f63SJim Harris  *
6744f11c7f63SJim Harris  * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
6745f11c7f63SJim Harris  *       SCIC_SDS_CONTROLLER object.
6746f11c7f63SJim Harris  *
6747f11c7f63SJim Harris  * @return none
6748f11c7f63SJim Harris  */
6749f11c7f63SJim Harris static
scic_sds_controller_stopping_state_enter(SCI_BASE_OBJECT_T * object)6750f11c7f63SJim Harris void scic_sds_controller_stopping_state_enter(
6751f11c7f63SJim Harris    SCI_BASE_OBJECT_T *object
6752f11c7f63SJim Harris )
6753f11c7f63SJim Harris {
6754f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
6755f11c7f63SJim Harris    this_controller= (SCIC_SDS_CONTROLLER_T *)object;
6756f11c7f63SJim Harris 
6757f11c7f63SJim Harris    scic_sds_controller_set_base_state_handlers(
6758f11c7f63SJim Harris       this_controller, SCI_BASE_CONTROLLER_STATE_STOPPING);
6759f11c7f63SJim Harris 
6760f11c7f63SJim Harris    // Stop all of the components for this controller in the reverse order
6761f11c7f63SJim Harris    // from which they are initialized.
6762f11c7f63SJim Harris    scic_sds_controller_stop_devices(this_controller);
6763f11c7f63SJim Harris    scic_sds_controller_stop_ports(this_controller);
6764f11c7f63SJim Harris 
6765f11c7f63SJim Harris    if (!scic_sds_controller_has_remote_devices_stopping(this_controller))
6766f11c7f63SJim Harris    {
6767f11c7f63SJim Harris       sci_base_state_machine_change_state(
6768f11c7f63SJim Harris          &this_controller->parent.state_machine,
6769f11c7f63SJim Harris          SCI_BASE_CONTROLLER_STATE_STOPPED
6770f11c7f63SJim Harris       );
6771f11c7f63SJim Harris    }
6772f11c7f63SJim Harris }
6773f11c7f63SJim Harris 
6774f11c7f63SJim Harris /**
6775f11c7f63SJim Harris  * This method implements the actions taken by the SCIC_SDS_CONTROLLER on exit
6776f11c7f63SJim Harris  * from the SCI_BASE_CONTROLLER_STATE_STOPPING.
6777f11c7f63SJim Harris  *    - This function stops the controller stopping timeout timer.
6778f11c7f63SJim Harris  *
6779f11c7f63SJim Harris  * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
6780f11c7f63SJim Harris  *       SCIC_SDS_CONTROLLER object.
6781f11c7f63SJim Harris  *
6782f11c7f63SJim Harris  * @return none
6783f11c7f63SJim Harris  */
6784f11c7f63SJim Harris static
scic_sds_controller_stopping_state_exit(SCI_BASE_OBJECT_T * object)6785f11c7f63SJim Harris void scic_sds_controller_stopping_state_exit(
6786f11c7f63SJim Harris    SCI_BASE_OBJECT_T *object
6787f11c7f63SJim Harris )
6788f11c7f63SJim Harris {
6789f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
6790f11c7f63SJim Harris    this_controller= (SCIC_SDS_CONTROLLER_T *)object;
6791f11c7f63SJim Harris 
6792f11c7f63SJim Harris    scic_cb_timer_stop(this_controller, this_controller->timeout_timer);
6793f11c7f63SJim Harris }
6794f11c7f63SJim Harris 
6795f11c7f63SJim Harris /**
6796f11c7f63SJim Harris  * This method implements the actions taken by the SCIC_SDS_CONTROLLER on
6797f11c7f63SJim Harris  * entry to the SCI_BASE_CONTROLLER_STATE_STOPPED.
6798f11c7f63SJim Harris  *    - Set the state handlers to the controllers stopped state.
6799f11c7f63SJim Harris  *
6800f11c7f63SJim Harris  * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
6801f11c7f63SJim Harris  *       SCIC_SDS_CONTROLLER object.
6802f11c7f63SJim Harris  *
6803f11c7f63SJim Harris  * @return none
6804f11c7f63SJim Harris  */
6805f11c7f63SJim Harris static
scic_sds_controller_stopped_state_enter(SCI_BASE_OBJECT_T * object)6806f11c7f63SJim Harris void scic_sds_controller_stopped_state_enter(
6807f11c7f63SJim Harris    SCI_BASE_OBJECT_T *object
6808f11c7f63SJim Harris )
6809f11c7f63SJim Harris {
6810f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
6811f11c7f63SJim Harris    this_controller= (SCIC_SDS_CONTROLLER_T *)object;
6812f11c7f63SJim Harris 
6813f11c7f63SJim Harris    scic_sds_controller_set_base_state_handlers(
6814f11c7f63SJim Harris       this_controller, SCI_BASE_CONTROLLER_STATE_STOPPED);
6815f11c7f63SJim Harris 
6816f11c7f63SJim Harris    // We are done with this timer until the next timer we initialize
6817f11c7f63SJim Harris    scic_cb_timer_destroy(
6818f11c7f63SJim Harris       this_controller,
6819f11c7f63SJim Harris       this_controller->timeout_timer
6820f11c7f63SJim Harris    );
6821f11c7f63SJim Harris    this_controller->timeout_timer = NULL;
6822f11c7f63SJim Harris 
6823f11c7f63SJim Harris    // Controller has stopped so disable all the phys on this controller
6824f11c7f63SJim Harris    scic_sds_controller_stop_phys(this_controller);
6825f11c7f63SJim Harris 
6826f11c7f63SJim Harris    scic_sds_port_configuration_agent_destroy(
6827f11c7f63SJim Harris       this_controller,
6828f11c7f63SJim Harris       &this_controller->port_agent
6829f11c7f63SJim Harris    );
6830f11c7f63SJim Harris 
6831f11c7f63SJim Harris    scic_cb_controller_stop_complete(this_controller, SCI_SUCCESS);
6832f11c7f63SJim Harris }
6833f11c7f63SJim Harris 
6834f11c7f63SJim Harris /**
6835f11c7f63SJim Harris  * This method implements the actions taken by the SCIC_SDS_CONTROLLER on
6836f11c7f63SJim Harris  * entry to the SCI_BASE_CONTROLLER_STATE_RESETTING.
6837f11c7f63SJim Harris  *    - Set the state handlers to the controllers resetting state.
6838f11c7f63SJim Harris  *    - Write to the SCU hardware reset register to force a reset
6839f11c7f63SJim Harris  *    - Transition to the SCI_BASE_CONTROLLER_STATE_RESET
6840f11c7f63SJim Harris  *
6841f11c7f63SJim Harris  * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
6842f11c7f63SJim Harris  *       SCIC_SDS_CONTROLLER object.
6843f11c7f63SJim Harris  *
6844f11c7f63SJim Harris  * @return none
6845f11c7f63SJim Harris  */
6846f11c7f63SJim Harris static
scic_sds_controller_resetting_state_enter(SCI_BASE_OBJECT_T * object)6847f11c7f63SJim Harris void scic_sds_controller_resetting_state_enter(
6848f11c7f63SJim Harris    SCI_BASE_OBJECT_T *object
6849f11c7f63SJim Harris )
6850f11c7f63SJim Harris {
6851f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
6852f11c7f63SJim Harris    this_controller= (SCIC_SDS_CONTROLLER_T *)object;
6853f11c7f63SJim Harris 
6854f11c7f63SJim Harris    SCIC_LOG_TRACE((
6855f11c7f63SJim Harris       sci_base_object_get_logger(this_controller),
6856f11c7f63SJim Harris       SCIC_LOG_OBJECT_CONTROLLER,
6857f11c7f63SJim Harris       "scic_sds_controller_resetting_state_enter(0x%x) enter\n",
6858f11c7f63SJim Harris       this_controller
6859f11c7f63SJim Harris    ));
6860f11c7f63SJim Harris 
6861f11c7f63SJim Harris    scic_sds_controller_set_base_state_handlers(
6862f11c7f63SJim Harris       this_controller, SCI_BASE_CONTROLLER_STATE_RESETTING);
6863f11c7f63SJim Harris 
6864f11c7f63SJim Harris    scic_sds_controller_reset_hardware(this_controller);
6865f11c7f63SJim Harris 
6866f11c7f63SJim Harris    sci_base_state_machine_change_state(
6867f11c7f63SJim Harris       scic_sds_controller_get_base_state_machine(this_controller),
6868f11c7f63SJim Harris       SCI_BASE_CONTROLLER_STATE_RESET
6869f11c7f63SJim Harris    );
6870f11c7f63SJim Harris }
6871f11c7f63SJim Harris 
6872f11c7f63SJim Harris static
scic_sds_abort_reqests(SCIC_SDS_CONTROLLER_T * controller,SCIC_SDS_REMOTE_DEVICE_T * remote_device,SCIC_SDS_PORT_T * port)6873f11c7f63SJim Harris SCI_STATUS scic_sds_abort_reqests(
6874f11c7f63SJim Harris         SCIC_SDS_CONTROLLER_T * controller,
6875f11c7f63SJim Harris         SCIC_SDS_REMOTE_DEVICE_T * remote_device,
6876f11c7f63SJim Harris         SCIC_SDS_PORT_T * port
6877f11c7f63SJim Harris )
6878f11c7f63SJim Harris {
6879f11c7f63SJim Harris     SCI_STATUS          status           = SCI_SUCCESS;
6880f11c7f63SJim Harris     SCI_STATUS          terminate_status = SCI_SUCCESS;
6881f11c7f63SJim Harris     SCIC_SDS_REQUEST_T *the_request;
6882f11c7f63SJim Harris     U32                 index;
6883f11c7f63SJim Harris     U32                 request_count;
6884f11c7f63SJim Harris 
6885f11c7f63SJim Harris     if (remote_device != NULL)
6886f11c7f63SJim Harris         request_count = remote_device->started_request_count;
6887f11c7f63SJim Harris     else if (port != NULL)
6888f11c7f63SJim Harris         request_count = port->started_request_count;
6889f11c7f63SJim Harris     else
6890f11c7f63SJim Harris         request_count = SCI_MAX_IO_REQUESTS;
6891f11c7f63SJim Harris 
6892f11c7f63SJim Harris 
6893f11c7f63SJim Harris     for (index = 0;
6894f11c7f63SJim Harris          (index < SCI_MAX_IO_REQUESTS) && (request_count > 0);
6895f11c7f63SJim Harris          index++)
6896f11c7f63SJim Harris     {
6897f11c7f63SJim Harris        the_request = controller->io_request_table[index];
6898f11c7f63SJim Harris 
6899f11c7f63SJim Harris        if (the_request != NULL)
6900f11c7f63SJim Harris        {
6901f11c7f63SJim Harris            if (the_request->target_device == remote_device
6902f11c7f63SJim Harris                    || the_request->target_device->owning_port == port
6903f11c7f63SJim Harris                    || (remote_device == NULL && port == NULL))
6904f11c7f63SJim Harris            {
6905f11c7f63SJim Harris                terminate_status = scic_controller_terminate_request(
6906f11c7f63SJim Harris                                      controller,
6907f11c7f63SJim Harris                                      the_request->target_device,
6908f11c7f63SJim Harris                                      the_request
6909f11c7f63SJim Harris                                   );
6910f11c7f63SJim Harris 
6911f11c7f63SJim Harris                if (terminate_status != SCI_SUCCESS)
6912f11c7f63SJim Harris                   status = terminate_status;
6913f11c7f63SJim Harris 
6914f11c7f63SJim Harris                request_count--;
6915f11c7f63SJim Harris            }
6916f11c7f63SJim Harris        }
6917f11c7f63SJim Harris     }
6918f11c7f63SJim Harris 
6919f11c7f63SJim Harris     return status;
6920f11c7f63SJim Harris }
6921f11c7f63SJim Harris 
scic_sds_terminate_reqests(SCIC_SDS_CONTROLLER_T * this_controller,SCIC_SDS_REMOTE_DEVICE_T * this_remote_device,SCIC_SDS_PORT_T * this_port)6922f11c7f63SJim Harris SCI_STATUS scic_sds_terminate_reqests(
6923f11c7f63SJim Harris         SCIC_SDS_CONTROLLER_T *this_controller,
6924f11c7f63SJim Harris         SCIC_SDS_REMOTE_DEVICE_T *this_remote_device,
6925f11c7f63SJim Harris         SCIC_SDS_PORT_T *this_port
6926f11c7f63SJim Harris )
6927f11c7f63SJim Harris {
6928f11c7f63SJim Harris     SCI_STATUS status = SCI_SUCCESS;
6929f11c7f63SJim Harris     SCI_STATUS abort_status = SCI_SUCCESS;
6930f11c7f63SJim Harris 
6931f11c7f63SJim Harris     // move all request to abort state
6932f11c7f63SJim Harris     abort_status = scic_sds_abort_reqests(this_controller, this_remote_device, this_port);
6933f11c7f63SJim Harris 
6934f11c7f63SJim Harris     if (abort_status != SCI_SUCCESS)
6935f11c7f63SJim Harris         status = abort_status;
6936f11c7f63SJim Harris 
6937f11c7f63SJim Harris     //move all request to complete state
6938f11c7f63SJim Harris     if (this_controller->parent.error == SCI_CONTROLLER_FATAL_MEMORY_ERROR)
6939f11c7f63SJim Harris         abort_status = scic_sds_abort_reqests(this_controller, this_remote_device, this_port);
6940f11c7f63SJim Harris 
6941f11c7f63SJim Harris     if (abort_status != SCI_SUCCESS)
6942f11c7f63SJim Harris         status = abort_status;
6943f11c7f63SJim Harris 
6944f11c7f63SJim Harris     return status;
6945f11c7f63SJim Harris }
6946f11c7f63SJim Harris 
6947f11c7f63SJim Harris static
scic_sds_terminate_all_requests(SCIC_SDS_CONTROLLER_T * controller)6948f11c7f63SJim Harris SCI_STATUS scic_sds_terminate_all_requests(
6949f11c7f63SJim Harris         SCIC_SDS_CONTROLLER_T * controller
6950f11c7f63SJim Harris )
6951f11c7f63SJim Harris {
6952f11c7f63SJim Harris     return scic_sds_terminate_reqests(controller, NULL, NULL);
6953f11c7f63SJim Harris }
6954f11c7f63SJim Harris 
6955f11c7f63SJim Harris /**
6956f11c7f63SJim Harris  * This method implements the actions taken by the SCIC_SDS_CONTROLLER on
6957f11c7f63SJim Harris  * entry to the SCI_BASE_CONTROLLER_STATE_FAILED.
6958f11c7f63SJim Harris  *    - Set the state handlers to the controllers failed state.
6959f11c7f63SJim Harris  *
6960f11c7f63SJim Harris  * @param[in] object This is the SCI_BASE_OBJECT which is cast to a
6961f11c7f63SJim Harris  *       SCIC_SDS_CONTROLLER object.
6962f11c7f63SJim Harris  *
6963f11c7f63SJim Harris  * @return none
6964f11c7f63SJim Harris  */
6965f11c7f63SJim Harris static
scic_sds_controller_failed_state_enter(SCI_BASE_OBJECT_T * object)6966f11c7f63SJim Harris void scic_sds_controller_failed_state_enter(
6967f11c7f63SJim Harris    SCI_BASE_OBJECT_T *object
6968f11c7f63SJim Harris )
6969f11c7f63SJim Harris {
6970f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T *this_controller;
6971f11c7f63SJim Harris    this_controller= (SCIC_SDS_CONTROLLER_T *)object;
6972f11c7f63SJim Harris 
6973f11c7f63SJim Harris    scic_sds_controller_set_base_state_handlers(
6974f11c7f63SJim Harris       this_controller, SCI_BASE_CONTROLLER_STATE_FAILED);
6975f11c7f63SJim Harris 
6976f11c7f63SJim Harris    if (this_controller->parent.error == SCI_CONTROLLER_FATAL_MEMORY_ERROR)
6977f11c7f63SJim Harris    scic_sds_terminate_all_requests(this_controller);
6978f11c7f63SJim Harris    else
6979f11c7f63SJim Harris        scic_sds_controller_release_resource(this_controller);
6980f11c7f63SJim Harris 
6981f11c7f63SJim Harris    //notify framework the controller failed.
6982f11c7f63SJim Harris    scic_cb_controller_error(this_controller,
6983f11c7f63SJim Harris            this_controller->parent.error);
6984f11c7f63SJim Harris }
6985f11c7f63SJim Harris 
6986f11c7f63SJim Harris // ---------------------------------------------------------------------------
6987f11c7f63SJim Harris 
6988f11c7f63SJim Harris SCI_BASE_STATE_T
6989f11c7f63SJim Harris    scic_sds_controller_state_table[SCI_BASE_CONTROLLER_MAX_STATES] =
6990f11c7f63SJim Harris {
6991f11c7f63SJim Harris    {
6992f11c7f63SJim Harris       SCI_BASE_CONTROLLER_STATE_INITIAL,
6993f11c7f63SJim Harris       scic_sds_controller_initial_state_enter,
6994f11c7f63SJim Harris       NULL,
6995f11c7f63SJim Harris    },
6996f11c7f63SJim Harris    {
6997f11c7f63SJim Harris       SCI_BASE_CONTROLLER_STATE_RESET,
6998f11c7f63SJim Harris       scic_sds_controller_reset_state_enter,
6999f11c7f63SJim Harris       NULL,
7000f11c7f63SJim Harris    },
7001f11c7f63SJim Harris    {
7002f11c7f63SJim Harris       SCI_BASE_CONTROLLER_STATE_INITIALIZING,
7003f11c7f63SJim Harris       scic_sds_controller_initializing_state_enter,
7004f11c7f63SJim Harris       NULL,
7005f11c7f63SJim Harris    },
7006f11c7f63SJim Harris    {
7007f11c7f63SJim Harris       SCI_BASE_CONTROLLER_STATE_INITIALIZED,
7008f11c7f63SJim Harris       scic_sds_controller_initialized_state_enter,
7009f11c7f63SJim Harris       NULL,
7010f11c7f63SJim Harris    },
7011f11c7f63SJim Harris    {
7012f11c7f63SJim Harris       SCI_BASE_CONTROLLER_STATE_STARTING,
7013f11c7f63SJim Harris       scic_sds_controller_starting_state_enter,
7014f11c7f63SJim Harris       scic_sds_controller_starting_state_exit,
7015f11c7f63SJim Harris    },
7016f11c7f63SJim Harris    {
7017f11c7f63SJim Harris       SCI_BASE_CONTROLLER_STATE_READY,
7018f11c7f63SJim Harris       scic_sds_controller_ready_state_enter,
7019f11c7f63SJim Harris       scic_sds_controller_ready_state_exit,
7020f11c7f63SJim Harris    },
7021f11c7f63SJim Harris    {
7022f11c7f63SJim Harris       SCI_BASE_CONTROLLER_STATE_RESETTING,
7023f11c7f63SJim Harris       scic_sds_controller_resetting_state_enter,
7024f11c7f63SJim Harris       NULL,
7025f11c7f63SJim Harris    },
7026f11c7f63SJim Harris    {
7027f11c7f63SJim Harris       SCI_BASE_CONTROLLER_STATE_STOPPING,
7028f11c7f63SJim Harris       scic_sds_controller_stopping_state_enter,
7029f11c7f63SJim Harris       scic_sds_controller_stopping_state_exit,
7030f11c7f63SJim Harris    },
7031f11c7f63SJim Harris    {
7032f11c7f63SJim Harris       SCI_BASE_CONTROLLER_STATE_STOPPED,
7033f11c7f63SJim Harris       scic_sds_controller_stopped_state_enter,
7034f11c7f63SJim Harris       NULL,
7035f11c7f63SJim Harris    },
7036f11c7f63SJim Harris    {
7037f11c7f63SJim Harris       SCI_BASE_CONTROLLER_STATE_FAILED,
7038f11c7f63SJim Harris       scic_sds_controller_failed_state_enter,
7039f11c7f63SJim Harris       NULL,
7040f11c7f63SJim Harris    }
7041f11c7f63SJim Harris };
7042f11c7f63SJim Harris 
7043