xref: /freebsd/sys/dev/isci/scil/scic_sds_smp_request.c (revision 685dc743dc3b5645e34836464128e1c0558b404b)
1f11c7f63SJim Harris /*-
2*718cf2ccSPedro F. Giffuni  * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
3*718cf2ccSPedro F. Giffuni  *
4f11c7f63SJim Harris  * This file is provided under a dual BSD/GPLv2 license.  When using or
5f11c7f63SJim Harris  * redistributing this file, you may do so under either license.
6f11c7f63SJim Harris  *
7f11c7f63SJim Harris  * GPL LICENSE SUMMARY
8f11c7f63SJim Harris  *
9f11c7f63SJim Harris  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
10f11c7f63SJim Harris  *
11f11c7f63SJim Harris  * This program is free software; you can redistribute it and/or modify
12f11c7f63SJim Harris  * it under the terms of version 2 of the GNU General Public License as
13f11c7f63SJim Harris  * published by the Free Software Foundation.
14f11c7f63SJim Harris  *
15f11c7f63SJim Harris  * This program is distributed in the hope that it will be useful, but
16f11c7f63SJim Harris  * WITHOUT ANY WARRANTY; without even the implied warranty of
17f11c7f63SJim Harris  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18f11c7f63SJim Harris  * General Public License for more details.
19f11c7f63SJim Harris  *
20f11c7f63SJim Harris  * You should have received a copy of the GNU General Public License
21f11c7f63SJim Harris  * along with this program; if not, write to the Free Software
22f11c7f63SJim Harris  * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
23f11c7f63SJim Harris  * The full GNU General Public License is included in this distribution
24f11c7f63SJim Harris  * in the file called LICENSE.GPL.
25f11c7f63SJim Harris  *
26f11c7f63SJim Harris  * BSD LICENSE
27f11c7f63SJim Harris  *
28f11c7f63SJim Harris  * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
29f11c7f63SJim Harris  * All rights reserved.
30f11c7f63SJim Harris  *
31f11c7f63SJim Harris  * Redistribution and use in source and binary forms, with or without
32f11c7f63SJim Harris  * modification, are permitted provided that the following conditions
33f11c7f63SJim Harris  * are met:
34f11c7f63SJim Harris  *
35f11c7f63SJim Harris  *   * Redistributions of source code must retain the above copyright
36f11c7f63SJim Harris  *     notice, this list of conditions and the following disclaimer.
37f11c7f63SJim Harris  *   * Redistributions in binary form must reproduce the above copyright
38f11c7f63SJim Harris  *     notice, this list of conditions and the following disclaimer in
39f11c7f63SJim Harris  *     the documentation and/or other materials provided with the
40f11c7f63SJim Harris  *     distribution.
41f11c7f63SJim Harris  *
42f11c7f63SJim Harris  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43f11c7f63SJim Harris  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44f11c7f63SJim Harris  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
45f11c7f63SJim Harris  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
46f11c7f63SJim Harris  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47f11c7f63SJim Harris  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
48f11c7f63SJim Harris  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
49f11c7f63SJim Harris  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50f11c7f63SJim Harris  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51f11c7f63SJim Harris  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52f11c7f63SJim Harris  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53f11c7f63SJim Harris  */
54f11c7f63SJim Harris 
55f11c7f63SJim Harris #include <sys/cdefs.h>
56f11c7f63SJim Harris #include <dev/isci/scil/scic_sds_smp_request.h>
57f11c7f63SJim Harris #include <dev/isci/scil/scic_sds_logger.h>
58f11c7f63SJim Harris #include <dev/isci/scil/scic_sds_controller.h>
59f11c7f63SJim Harris #include <dev/isci/scil/scic_sds_remote_device.h>
60f11c7f63SJim Harris #include <dev/isci/scil/scic_remote_device.h>
61f11c7f63SJim Harris #include <dev/isci/scil/sci_util.h>
62f11c7f63SJim Harris #include <dev/isci/sci_environment.h>
63f11c7f63SJim Harris #include <dev/isci/scil/intel_sas.h>
64f11c7f63SJim Harris #include <dev/isci/scil/scic_sds_request.h>
65f11c7f63SJim Harris #include <dev/isci/scil/scic_controller.h>
66f11c7f63SJim Harris #include <dev/isci/scil/scu_completion_codes.h>
67f11c7f63SJim Harris #include <dev/isci/scil/scu_task_context.h>
68f11c7f63SJim Harris #include <dev/isci/scil/sci_base_state_machine.h>
69f11c7f63SJim Harris 
70f11c7f63SJim Harris /**
71f11c7f63SJim Harris  * This method return the memory space required for STP PIO requests.
72f11c7f63SJim Harris  *
73f11c7f63SJim Harris  * @return U32
74f11c7f63SJim Harris  */
scic_sds_smp_request_get_object_size(void)75f11c7f63SJim Harris U32 scic_sds_smp_request_get_object_size(void)
76f11c7f63SJim Harris {
77f11c7f63SJim Harris    return   sizeof(SCIC_SDS_REQUEST_T)
78f11c7f63SJim Harris           + sizeof(SMP_REQUEST_T)
79f11c7f63SJim Harris           + sizeof(U32)
80f11c7f63SJim Harris           + sizeof(SMP_RESPONSE_T)
81f11c7f63SJim Harris           + sizeof(U32)
82f11c7f63SJim Harris           + sizeof(SCU_TASK_CONTEXT_T)
83f11c7f63SJim Harris           + CACHE_LINE_SIZE;
84f11c7f63SJim Harris }
85f11c7f63SJim Harris 
86f11c7f63SJim Harris /**
87f11c7f63SJim Harris  * This macro returns the address of the smp command buffer in the smp request
88f11c7f63SJim Harris  * memory. No need to cast to SMP request type.
89f11c7f63SJim Harris  */
90f11c7f63SJim Harris #define scic_sds_smp_request_get_command_buffer_unaligned(memory) \
91f11c7f63SJim Harris    ( ((char *)(memory)) + sizeof(SCIC_SDS_REQUEST_T) )
92f11c7f63SJim Harris 
93f11c7f63SJim Harris /**
94f11c7f63SJim Harris  * This macro aligns the smp command buffer in DWORD alignment
95f11c7f63SJim Harris */
96f11c7f63SJim Harris #define scic_sds_smp_request_align_command_buffer(address) \
97f11c7f63SJim Harris    ((char *)( \
98f11c7f63SJim Harris       (((POINTER_UINT)(address)) + (sizeof(U32) - 1)) \
99f11c7f63SJim Harris          & ~(sizeof(U32)- 1) \
100f11c7f63SJim Harris    ))
101f11c7f63SJim Harris 
102f11c7f63SJim Harris /**
103f11c7f63SJim Harris  * This macro returns the DWORD-aligned smp command buffer
104f11c7f63SJim Harris */
105f11c7f63SJim Harris #define scic_sds_smp_request_get_command_buffer(memory) \
106f11c7f63SJim Harris    ((char *)  \
107f11c7f63SJim Harris       ((char *)scic_sds_smp_request_align_command_buffer( \
108f11c7f63SJim Harris          (char *) scic_sds_smp_request_get_command_buffer_unaligned(memory) \
109f11c7f63SJim Harris    )))
110f11c7f63SJim Harris 
111f11c7f63SJim Harris /**
112f11c7f63SJim Harris  * This macro returns the address of the smp response buffer in the smp request
113f11c7f63SJim Harris  * memory.
114f11c7f63SJim Harris  */
115f11c7f63SJim Harris #define scic_sds_smp_request_get_response_buffer_unaligned(memory) \
116f11c7f63SJim Harris    ( ((char *)(scic_sds_smp_request_get_command_buffer(memory))) \
117f11c7f63SJim Harris       + sizeof(SMP_REQUEST_T) )
118f11c7f63SJim Harris 
119f11c7f63SJim Harris /**
120f11c7f63SJim Harris  * This macro aligns the smp command buffer in DWORD alignment
121f11c7f63SJim Harris */
122f11c7f63SJim Harris #define scic_sds_smp_request_align_response_buffer(address) \
123f11c7f63SJim Harris    ((char *)( \
124f11c7f63SJim Harris       (((POINTER_UINT)(address)) + (sizeof(U32) - 1)) \
125f11c7f63SJim Harris          & ~(sizeof(U32)- 1) \
126f11c7f63SJim Harris    ))
127f11c7f63SJim Harris 
128f11c7f63SJim Harris /**
129f11c7f63SJim Harris  * This macro returns the DWORD-aligned smp resposne buffer
130f11c7f63SJim Harris */
131f11c7f63SJim Harris #define scic_sds_smp_request_get_response_buffer(memory) \
132f11c7f63SJim Harris    ((char *)  \
133f11c7f63SJim Harris       ((char *)scic_sds_smp_request_align_response_buffer( \
134f11c7f63SJim Harris          (char *) scic_sds_smp_request_get_response_buffer_unaligned(memory) \
135f11c7f63SJim Harris    )))
136f11c7f63SJim Harris 
137f11c7f63SJim Harris /**
138f11c7f63SJim Harris  * This macro returs the task context buffer for the SMP request.
139f11c7f63SJim Harris  */
140f11c7f63SJim Harris #define scic_sds_smp_request_get_task_context_buffer_unaligned(memory) \
141f11c7f63SJim Harris    ((SCU_TASK_CONTEXT_T *)( \
142f11c7f63SJim Harris         ((char *)(scic_sds_smp_request_get_response_buffer(memory))) \
143f11c7f63SJim Harris       + sizeof(SMP_RESPONSE_T) \
144f11c7f63SJim Harris    ))
145f11c7f63SJim Harris 
146f11c7f63SJim Harris /**
147f11c7f63SJim Harris  * This macro returns the dword-aligned smp task context buffer
148f11c7f63SJim Harris  */
149f11c7f63SJim Harris #define scic_sds_smp_request_get_task_context_buffer(memory) \
150f11c7f63SJim Harris    ((SCU_TASK_CONTEXT_T *)( \
151f11c7f63SJim Harris       ((char *)scic_sds_request_align_task_context_buffer( \
152f11c7f63SJim Harris          (char *)scic_sds_smp_request_get_task_context_buffer_unaligned(memory)) \
153f11c7f63SJim Harris    )))
154f11c7f63SJim Harris 
155f11c7f63SJim Harris /**
156f11c7f63SJim Harris  * @brief This method build the remainder of the IO request object.
157f11c7f63SJim Harris  *
158f11c7f63SJim Harris  * @pre The scic_sds_general_request_construct() must be called before this
159f11c7f63SJim Harris  *      call is valid.
160f11c7f63SJim Harris  *
161f11c7f63SJim Harris  * @param[in] this_request This parameter specifies the request object being
162f11c7f63SJim Harris  *            constructed.
163f11c7f63SJim Harris  *
164f11c7f63SJim Harris  * @return none
165f11c7f63SJim Harris  */
166f11c7f63SJim Harris 
scic_sds_smp_request_assign_buffers(SCIC_SDS_REQUEST_T * this_request)167f11c7f63SJim Harris void scic_sds_smp_request_assign_buffers(
168f11c7f63SJim Harris    SCIC_SDS_REQUEST_T *this_request
169f11c7f63SJim Harris )
170f11c7f63SJim Harris {
171f11c7f63SJim Harris    // Assign all of the buffer pointers
172f11c7f63SJim Harris    this_request->command_buffer =
173f11c7f63SJim Harris       scic_sds_smp_request_get_command_buffer(this_request);
174f11c7f63SJim Harris    this_request->response_buffer =
175f11c7f63SJim Harris       scic_sds_smp_request_get_response_buffer(this_request);
176f11c7f63SJim Harris    this_request->sgl_element_pair_buffer = NULL;
177f11c7f63SJim Harris 
178f11c7f63SJim Harris    if (this_request->was_tag_assigned_by_user == FALSE)
179f11c7f63SJim Harris    {
180f11c7f63SJim Harris       this_request->task_context_buffer =
181f11c7f63SJim Harris          scic_sds_smp_request_get_task_context_buffer(this_request);
182f11c7f63SJim Harris    }
183f11c7f63SJim Harris 
184f11c7f63SJim Harris }
185f11c7f63SJim Harris /**
186f11c7f63SJim Harris  * @brief This method is called by the SCI user to build an SMP
187f11c7f63SJim Harris  *        IO request.
188f11c7f63SJim Harris  *
189f11c7f63SJim Harris  * @pre
190f11c7f63SJim Harris  *        - The user must have previously called scic_io_request_construct()
191f11c7f63SJim Harris  *          on the supplied IO request.
192f11c7f63SJim Harris  *
193f11c7f63SJim Harris  * @param[in]  scic_io_request This parameter specifies the handle to the
194f11c7f63SJim Harris  *             io request object to be built.
195f11c7f63SJim Harris  *
196f11c7f63SJim Harris  * @return Indicate if the controller successfully built the IO request.
197f11c7f63SJim Harris  * @retval SCI_SUCCESS This value is returned if the IO request was
198f11c7f63SJim Harris  *         successfully built.
199f11c7f63SJim Harris  * @retval SCI_FAILURE_UNSUPPORTED_PROTOCOL This value is returned if the
200f11c7f63SJim Harris  *         remote_device does not support the SMP protocol.
201f11c7f63SJim Harris  * @retval SCI_FAILURE_INVALID_ASSOCIATION This value is returned if the
202f11c7f63SJim Harris  *         user did not properly set the association between the SCIC IO
203f11c7f63SJim Harris  *         request and the user's IO request.  Please refer to the
204f11c7f63SJim Harris  *         sci_object_set_association() routine for more
205f11c7f63SJim Harris  *         information.
206f11c7f63SJim Harris  */
scic_io_request_construct_smp(SCI_IO_REQUEST_HANDLE_T scic_smp_request)207f11c7f63SJim Harris SCI_STATUS scic_io_request_construct_smp(
208f11c7f63SJim Harris    SCI_IO_REQUEST_HANDLE_T  scic_smp_request
209f11c7f63SJim Harris )
210f11c7f63SJim Harris {
211f11c7f63SJim Harris    SMP_REQUEST_T smp_request;
212f11c7f63SJim Harris 
213f11c7f63SJim Harris    SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *) scic_smp_request;
214f11c7f63SJim Harris    SCIC_LOG_TRACE((
215f11c7f63SJim Harris       sci_base_object_get_logger(this_request),
216f11c7f63SJim Harris       SCIC_LOG_OBJECT_SMP_IO_REQUEST,
217f11c7f63SJim Harris       "scic_io_request_construct_smp(0x%x) enter\n",
218f11c7f63SJim Harris       this_request
219f11c7f63SJim Harris    ));
220f11c7f63SJim Harris 
221f11c7f63SJim Harris    this_request->protocol                     = SCIC_SMP_PROTOCOL;
222f11c7f63SJim Harris    this_request->has_started_substate_machine = TRUE;
223f11c7f63SJim Harris 
224f11c7f63SJim Harris    // Construct the started sub-state machine.
225f11c7f63SJim Harris    sci_base_state_machine_construct(
226f11c7f63SJim Harris       &this_request->started_substate_machine,
227f11c7f63SJim Harris       &this_request->parent.parent,
228f11c7f63SJim Harris       scic_sds_smp_request_started_substate_table,
229f11c7f63SJim Harris       SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE
230f11c7f63SJim Harris    );
231f11c7f63SJim Harris 
232f11c7f63SJim Harris    // Construct the SMP SCU Task Context
233f11c7f63SJim Harris    memcpy((char *)&smp_request,
234f11c7f63SJim Harris         this_request->command_buffer,
235f11c7f63SJim Harris         sizeof(SMP_REQUEST_T));
236f11c7f63SJim Harris 
237f11c7f63SJim Harris    // Look at the SMP requests' header fields; for certain SAS 1.x SMP
238f11c7f63SJim Harris    // functions under SAS 2.0, a zero request length really indicates
239f11c7f63SJim Harris    // a non-zero default length.
240f11c7f63SJim Harris    if( smp_request.header.request_length == 0 )
241f11c7f63SJim Harris    {
242f11c7f63SJim Harris        switch( smp_request.header.function )
243f11c7f63SJim Harris        {
244f11c7f63SJim Harris        case SMP_FUNCTION_DISCOVER:
245f11c7f63SJim Harris        case SMP_FUNCTION_REPORT_PHY_ERROR_LOG:
246f11c7f63SJim Harris        case SMP_FUNCTION_REPORT_PHY_SATA:
247f11c7f63SJim Harris        case SMP_FUNCTION_REPORT_ROUTE_INFORMATION:
248f11c7f63SJim Harris            smp_request.header.request_length = 2;
249f11c7f63SJim Harris            break;
250f11c7f63SJim Harris        case SMP_FUNCTION_CONFIGURE_ROUTE_INFORMATION:
251f11c7f63SJim Harris        case SMP_FUNCTION_PHY_CONTROL:
252f11c7f63SJim Harris        case SMP_FUNCTION_PHY_TEST:
253f11c7f63SJim Harris            smp_request.header.request_length = 9;
254f11c7f63SJim Harris            break;
255f11c7f63SJim Harris        // Default - zero is a valid default for 2.0.
256f11c7f63SJim Harris        }
257f11c7f63SJim Harris    }
258f11c7f63SJim Harris 
259f11c7f63SJim Harris    scu_smp_request_construct_task_context(
260f11c7f63SJim Harris       this_request,
261f11c7f63SJim Harris       &smp_request
262f11c7f63SJim Harris    );
263f11c7f63SJim Harris 
264f11c7f63SJim Harris    sci_base_state_machine_change_state(
265f11c7f63SJim Harris       &this_request->parent.state_machine,
266f11c7f63SJim Harris       SCI_BASE_REQUEST_STATE_CONSTRUCTED
267f11c7f63SJim Harris    );
268f11c7f63SJim Harris 
269f11c7f63SJim Harris    return SCI_SUCCESS;
270f11c7f63SJim Harris }
271f11c7f63SJim Harris 
272f11c7f63SJim Harris /**
273f11c7f63SJim Harris  * @brief This method is called by the SCI user to build an SMP pass-through
274f11c7f63SJim Harris  *        IO request.
275f11c7f63SJim Harris  *
276f11c7f63SJim Harris  * @pre
277f11c7f63SJim Harris  *        - The user must have previously called scic_io_request_construct()
278f11c7f63SJim Harris  *          on the supplied IO request.
279f11c7f63SJim Harris  *
280f11c7f63SJim Harris  * @param[in]  scic_smp_request This parameter specifies the handle to the
281f11c7f63SJim Harris  *             io request object to be built.
282f11c7f63SJim Harris  *
283f11c7f63SJim Harris  * @param[in]  passthru_cb This parameter specifies the pointer to the callback
284f11c7f63SJim Harris  *             structure that contains the function pointers
285f11c7f63SJim Harris  *
286f11c7f63SJim Harris  * @return Indicate if the controller successfully built the IO request.
287f11c7f63SJim Harris  */
scic_io_request_construct_smp_pass_through(SCI_IO_REQUEST_HANDLE_T scic_smp_request,SCIC_SMP_PASSTHRU_REQUEST_CALLBACKS_T * passthru_cb)288f11c7f63SJim Harris SCI_STATUS scic_io_request_construct_smp_pass_through(
289f11c7f63SJim Harris    SCI_IO_REQUEST_HANDLE_T  scic_smp_request,
290f11c7f63SJim Harris    SCIC_SMP_PASSTHRU_REQUEST_CALLBACKS_T *passthru_cb
291f11c7f63SJim Harris )
292f11c7f63SJim Harris {
293f11c7f63SJim Harris    SMP_REQUEST_T smp_request;
294f11c7f63SJim Harris    U8 * request_buffer;
295f11c7f63SJim Harris    U32 request_buffer_length_in_bytes;
296f11c7f63SJim Harris 
297f11c7f63SJim Harris    SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *) scic_smp_request;
298f11c7f63SJim Harris    SCIC_LOG_TRACE((
299f11c7f63SJim Harris       sci_base_object_get_logger(this_request),
300f11c7f63SJim Harris       SCIC_LOG_OBJECT_SMP_IO_REQUEST,
301f11c7f63SJim Harris       "scic_io_request_construct_smp_pass_through(0x%x) enter\n",
302f11c7f63SJim Harris       this_request
303f11c7f63SJim Harris    ));
304f11c7f63SJim Harris 
305f11c7f63SJim Harris    this_request->protocol                     = SCIC_SMP_PROTOCOL;
306f11c7f63SJim Harris    this_request->has_started_substate_machine = TRUE;
307f11c7f63SJim Harris 
308f11c7f63SJim Harris    // Call the callback function to retrieve the SMP passthrough request
309f11c7f63SJim Harris    request_buffer_length_in_bytes = passthru_cb->scic_cb_smp_passthru_get_request (
310f11c7f63SJim Harris                                        (void *)this_request,
311f11c7f63SJim Harris                                        &request_buffer
312f11c7f63SJim Harris                                     );
313f11c7f63SJim Harris 
314f11c7f63SJim Harris    //copy the request to smp request
315f11c7f63SJim Harris    memcpy((char *)&smp_request.request.vendor_specific_request,
316f11c7f63SJim Harris         request_buffer,
317f11c7f63SJim Harris         request_buffer_length_in_bytes);
318f11c7f63SJim Harris 
319f11c7f63SJim Harris    //the header length in smp_request is in dwords - the sas spec has similar way,
320f11c7f63SJim Harris    //but the csmi header contains the number of bytes, so we need to convert the
321f11c7f63SJim Harris    //number of bytes to number of dwords
322f11c7f63SJim Harris    smp_request.header.request_length = (U8) (request_buffer_length_in_bytes / sizeof (U32));
323f11c7f63SJim Harris 
324f11c7f63SJim Harris    //Grab the other needed fields from the smp request using callbacks
325f11c7f63SJim Harris    smp_request.header.smp_frame_type = passthru_cb->scic_cb_smp_passthru_get_frame_type ((void *)this_request);
326f11c7f63SJim Harris    smp_request.header.function = passthru_cb->scic_cb_smp_passthru_get_function ((void *)this_request);
327f11c7f63SJim Harris    smp_request.header.allocated_response_length = passthru_cb->scic_cb_smp_passthru_get_allocated_response_length((void *)this_request);
328f11c7f63SJim Harris 
329f11c7f63SJim Harris    // Construct the started sub-state machine.
330f11c7f63SJim Harris    sci_base_state_machine_construct(
331f11c7f63SJim Harris       &this_request->started_substate_machine,
332f11c7f63SJim Harris       &this_request->parent.parent,
333f11c7f63SJim Harris       scic_sds_smp_request_started_substate_table,
334f11c7f63SJim Harris       SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE
335f11c7f63SJim Harris    );
336f11c7f63SJim Harris 
337f11c7f63SJim Harris    // Construct the SMP SCU Task Context
338f11c7f63SJim Harris    scu_smp_request_construct_task_context (this_request, &smp_request);
339f11c7f63SJim Harris 
340f11c7f63SJim Harris    sci_base_state_machine_change_state(
341f11c7f63SJim Harris       &this_request->parent.state_machine,
342f11c7f63SJim Harris       SCI_BASE_REQUEST_STATE_CONSTRUCTED
343f11c7f63SJim Harris    );
344f11c7f63SJim Harris 
345f11c7f63SJim Harris    return SCI_SUCCESS;
346f11c7f63SJim Harris }
347f11c7f63SJim Harris 
348f11c7f63SJim Harris /**
349f11c7f63SJim Harris  * @brief This method will fill in the SCU Task Context for a SMP request. The
350f11c7f63SJim Harris  *        following important settings are utilized:
351f11c7f63SJim Harris  *
352f11c7f63SJim Harris  *          -# task_type == SCU_TASK_TYPE_SMP.  This simply indicates
353f11c7f63SJim Harris  *             that a normal request type (i.e. non-raw frame) is being
354f11c7f63SJim Harris  *             utilized to perform task management.
355453130d9SPedro F. Giffuni  *          -# control_frame == 1.  This ensures that the proper endianness
356f11c7f63SJim Harris  *             is set so that the bytes are transmitted in the right order
357f11c7f63SJim Harris  *             for a smp request frame.
358f11c7f63SJim Harris  *
359f11c7f63SJim Harris  * @param[in] this_request This parameter specifies the smp request object
360f11c7f63SJim Harris  *            being constructed.
361f11c7f63SJim Harris  *
362f11c7f63SJim Harris  * @return none
363f11c7f63SJim Harris  */
scu_smp_request_construct_task_context(SCIC_SDS_REQUEST_T * this_request,SMP_REQUEST_T * smp_request)364f11c7f63SJim Harris void scu_smp_request_construct_task_context(
365f11c7f63SJim Harris    SCIC_SDS_REQUEST_T *this_request,
366f11c7f63SJim Harris    SMP_REQUEST_T      *smp_request
367f11c7f63SJim Harris )
368f11c7f63SJim Harris {
369f11c7f63SJim Harris    SCI_PHYSICAL_ADDRESS      physical_address;
370f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T    *owning_controller;
371f11c7f63SJim Harris    SCIC_SDS_REMOTE_DEVICE_T *target_device;
372f11c7f63SJim Harris    SCIC_SDS_PORT_T          *target_port;
373f11c7f63SJim Harris    SCU_TASK_CONTEXT_T *task_context;
374f11c7f63SJim Harris 
375f11c7f63SJim Harris    //byte swap the smp request.
376f11c7f63SJim Harris    scic_word_copy_with_swap(
377f11c7f63SJim Harris       this_request->command_buffer,
378f11c7f63SJim Harris       (U32*) smp_request,
379f11c7f63SJim Harris       sizeof(SMP_REQUEST_T)/sizeof(U32)
380f11c7f63SJim Harris    );
381f11c7f63SJim Harris 
382f11c7f63SJim Harris    task_context = scic_sds_request_get_task_context(this_request);
383f11c7f63SJim Harris 
384f11c7f63SJim Harris    owning_controller = scic_sds_request_get_controller(this_request);
385f11c7f63SJim Harris    target_device = scic_sds_request_get_device(this_request);
386f11c7f63SJim Harris    target_port = scic_sds_request_get_port(this_request);
387f11c7f63SJim Harris 
388f11c7f63SJim Harris    SCIC_LOG_TRACE((
389f11c7f63SJim Harris       sci_base_object_get_logger(this_request),
390f11c7f63SJim Harris       SCIC_LOG_OBJECT_SMP_IO_REQUEST,
391f11c7f63SJim Harris       "scu_smp_request_construct_task_context(0x%x) contents\n"
392f11c7f63SJim Harris       "   reqlen=%x; function=%x;\n",
393f11c7f63SJim Harris       this_request,
394f11c7f63SJim Harris       smp_request->header.request_length,
395f11c7f63SJim Harris       smp_request->header.function
396f11c7f63SJim Harris    ));
397f11c7f63SJim Harris 
398f11c7f63SJim Harris    // Fill in the TC with the its required data
399f11c7f63SJim Harris    // 00h
400f11c7f63SJim Harris    task_context->priority = 0;
401f11c7f63SJim Harris    task_context->initiator_request = 1;
402f11c7f63SJim Harris    task_context->connection_rate =
403f11c7f63SJim Harris       scic_remote_device_get_connection_rate(target_device);
404f11c7f63SJim Harris    task_context->protocol_engine_index =
405f11c7f63SJim Harris       scic_sds_controller_get_protocol_engine_group(owning_controller);
406f11c7f63SJim Harris    task_context->logical_port_index =
407f11c7f63SJim Harris       scic_sds_port_get_index(target_port);
408f11c7f63SJim Harris    task_context->protocol_type = SCU_TASK_CONTEXT_PROTOCOL_SMP;
409f11c7f63SJim Harris    task_context->abort = 0;
410f11c7f63SJim Harris    task_context->valid = SCU_TASK_CONTEXT_VALID;
411f11c7f63SJim Harris    task_context->context_type = SCU_TASK_CONTEXT_TYPE;
412f11c7f63SJim Harris 
413f11c7f63SJim Harris    //04h
414f11c7f63SJim Harris    task_context->remote_node_index = this_request->target_device->rnc->remote_node_index;
415f11c7f63SJim Harris    task_context->command_code = 0;
416f11c7f63SJim Harris    task_context->task_type = SCU_TASK_TYPE_SMP_REQUEST;
417f11c7f63SJim Harris 
418f11c7f63SJim Harris    //08h
419f11c7f63SJim Harris    task_context->link_layer_control = 0;
420f11c7f63SJim Harris    task_context->do_not_dma_ssp_good_response = 1;
421f11c7f63SJim Harris    task_context->strict_ordering = 0;
422f11c7f63SJim Harris    task_context->control_frame = 1;
423f11c7f63SJim Harris    task_context->timeout_enable = 0;
424f11c7f63SJim Harris    task_context->block_guard_enable = 0;
425f11c7f63SJim Harris 
426f11c7f63SJim Harris    //0ch
427f11c7f63SJim Harris    task_context->address_modifier = 0;
428f11c7f63SJim Harris 
429f11c7f63SJim Harris    //10h
430f11c7f63SJim Harris    task_context->ssp_command_iu_length = smp_request->header.request_length;
431f11c7f63SJim Harris 
432f11c7f63SJim Harris    //14h
433f11c7f63SJim Harris    task_context->transfer_length_bytes = 0;
434f11c7f63SJim Harris 
435f11c7f63SJim Harris    //18h ~ 30h, protocol specific
436f11c7f63SJim Harris    // since commandIU has been build by framework at this point, we just
437f11c7f63SJim Harris    // copy the frist DWord from command IU to this location.
438f11c7f63SJim Harris    memcpy((void *)(&task_context->type.smp), this_request->command_buffer, sizeof(U32) );
439f11c7f63SJim Harris 
440f11c7f63SJim Harris    //40h
441f11c7f63SJim Harris    // "For SMP you could program it to zero. We would prefer that way so that
442f11c7f63SJim Harris    // done code will be consistent." - Venki
443f11c7f63SJim Harris    task_context->task_phase = 0;
444f11c7f63SJim Harris 
445f11c7f63SJim Harris    if (this_request->was_tag_assigned_by_user)
446f11c7f63SJim Harris    {
447f11c7f63SJim Harris       // Build the task context now since we have already read the data
448f11c7f63SJim Harris       this_request->post_context = (
449f11c7f63SJim Harris            SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
450f11c7f63SJim Harris          | (
451f11c7f63SJim Harris                 scic_sds_controller_get_protocol_engine_group(owning_controller)
452f11c7f63SJim Harris              << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
453f11c7f63SJim Harris            )
454f11c7f63SJim Harris          | (
455f11c7f63SJim Harris                  scic_sds_port_get_index(target_port)
456f11c7f63SJim Harris               << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
457f11c7f63SJim Harris            )
458f11c7f63SJim Harris          | scic_sds_io_tag_get_index(this_request->io_tag)
459f11c7f63SJim Harris       );
460f11c7f63SJim Harris    }
461f11c7f63SJim Harris    else
462f11c7f63SJim Harris    {
463f11c7f63SJim Harris       // Build the task context now since we have already read the data
464f11c7f63SJim Harris       this_request->post_context = (
465f11c7f63SJim Harris            SCU_CONTEXT_COMMAND_REQUEST_TYPE_POST_TC
466f11c7f63SJim Harris          | (
467f11c7f63SJim Harris                scic_sds_controller_get_protocol_engine_group(owning_controller)
468f11c7f63SJim Harris             << SCU_CONTEXT_COMMAND_PROTOCOL_ENGINE_GROUP_SHIFT
469f11c7f63SJim Harris            )
470f11c7f63SJim Harris          | (
471f11c7f63SJim Harris                 scic_sds_port_get_index(target_port)
472f11c7f63SJim Harris              << SCU_CONTEXT_COMMAND_LOGICAL_PORT_SHIFT
473f11c7f63SJim Harris            )
474f11c7f63SJim Harris          // This is not assigned because we have to wait until we get a TCi
475f11c7f63SJim Harris       );
476f11c7f63SJim Harris    }
477f11c7f63SJim Harris 
478f11c7f63SJim Harris    // Copy the physical address for the command buffer to the SCU Task Context
479f11c7f63SJim Harris    // command buffer should not contain command header.
480f11c7f63SJim Harris    scic_cb_io_request_get_physical_address(
481f11c7f63SJim Harris          scic_sds_request_get_controller(this_request),
482f11c7f63SJim Harris          this_request,
483f11c7f63SJim Harris          ((char *)(this_request->command_buffer) + sizeof(U32)),
484f11c7f63SJim Harris          &physical_address
485f11c7f63SJim Harris       );
486f11c7f63SJim Harris 
487f11c7f63SJim Harris    task_context->command_iu_upper =
488f11c7f63SJim Harris       sci_cb_physical_address_upper(physical_address);
489f11c7f63SJim Harris    task_context->command_iu_lower =
490f11c7f63SJim Harris       sci_cb_physical_address_lower(physical_address);
491f11c7f63SJim Harris 
492f11c7f63SJim Harris 
493f11c7f63SJim Harris    //SMP response comes as UF, so no need to set response IU address.
494f11c7f63SJim Harris    task_context->response_iu_upper = 0;
495f11c7f63SJim Harris    task_context->response_iu_lower = 0;
496f11c7f63SJim Harris }
497f11c7f63SJim Harris 
498f11c7f63SJim Harris //******************************************************************************
499f11c7f63SJim Harris //* SMP REQUEST STATE MACHINE
500f11c7f63SJim Harris //******************************************************************************
501f11c7f63SJim Harris 
502f11c7f63SJim Harris /**
503f11c7f63SJim Harris  * @brief This method processes an unsolicited frame while the SMP request is
504f11c7f63SJim Harris  *        waiting for a response frame.  It will copy the response data, release
505f11c7f63SJim Harris  *        the unsolicited frame, and transition the request to the
506f11c7f63SJim Harris  *        SCI_BASE_REQUEST_STATE_COMPLETED state.
507f11c7f63SJim Harris  *
508f11c7f63SJim Harris  * @param[in] this_request This parameter specifies the request for which
509f11c7f63SJim Harris  *            the unsolicited frame was received.
510f11c7f63SJim Harris  * @param[in] frame_index This parameter indicates the unsolicited frame
511f11c7f63SJim Harris  *            index that should contain the response.
512f11c7f63SJim Harris  *
513f11c7f63SJim Harris  * @return This method returns an indication of whether the response
514f11c7f63SJim Harris  *         frame was handled successfully or not.
515f11c7f63SJim Harris  * @retval SCI_SUCCESS Currently this value is always returned and indicates
516f11c7f63SJim Harris  *         successful processing of the TC response.
517f11c7f63SJim Harris  */
518f11c7f63SJim Harris static
scic_sds_smp_request_await_response_frame_handler(SCIC_SDS_REQUEST_T * this_request,U32 frame_index)519f11c7f63SJim Harris SCI_STATUS scic_sds_smp_request_await_response_frame_handler(
520f11c7f63SJim Harris    SCIC_SDS_REQUEST_T * this_request,
521f11c7f63SJim Harris    U32                  frame_index
522f11c7f63SJim Harris )
523f11c7f63SJim Harris {
524f11c7f63SJim Harris    SCI_STATUS              status;
525f11c7f63SJim Harris    void                  * frame_header;
526f11c7f63SJim Harris    SMP_RESPONSE_HEADER_T * this_frame_header;
527f11c7f63SJim Harris    U8                    * user_smp_buffer = this_request->response_buffer;
528f11c7f63SJim Harris 
529f11c7f63SJim Harris    // Save off the controller, so that we do not touch the request after it
530f11c7f63SJim Harris    //  is completed.
531f11c7f63SJim Harris    SCIC_SDS_CONTROLLER_T * controller = scic_sds_request_get_controller(this_request);
532f11c7f63SJim Harris 
533f11c7f63SJim Harris    SCIC_LOG_TRACE((
534f11c7f63SJim Harris       sci_base_object_get_logger(this_request),
535f11c7f63SJim Harris       SCIC_LOG_OBJECT_SMP_IO_REQUEST,
536f11c7f63SJim Harris       "scic_sds_smp_request_await_response_frame_handler(0x%x, 0x%x) enter\n",
537f11c7f63SJim Harris       this_request, frame_index
538f11c7f63SJim Harris    ));
539f11c7f63SJim Harris 
540f11c7f63SJim Harris    status = scic_sds_unsolicited_frame_control_get_header(
541f11c7f63SJim Harris       &(controller->uf_control),
542f11c7f63SJim Harris       frame_index,
543f11c7f63SJim Harris       &frame_header
544f11c7f63SJim Harris    );
545f11c7f63SJim Harris 
546f11c7f63SJim Harris    //byte swap the header.
547f11c7f63SJim Harris    scic_word_copy_with_swap(
548f11c7f63SJim Harris       (U32*) user_smp_buffer,
549f11c7f63SJim Harris       frame_header,
550f11c7f63SJim Harris       sizeof(SMP_RESPONSE_HEADER_T)/sizeof(U32)
551f11c7f63SJim Harris    );
552f11c7f63SJim Harris    this_frame_header = (SMP_RESPONSE_HEADER_T*) user_smp_buffer;
553f11c7f63SJim Harris 
554f11c7f63SJim Harris    if (this_frame_header->smp_frame_type == SMP_FRAME_TYPE_RESPONSE)
555f11c7f63SJim Harris    {
556f11c7f63SJim Harris       void * smp_response_buffer;
557f11c7f63SJim Harris 
558f11c7f63SJim Harris       status = scic_sds_unsolicited_frame_control_get_buffer(
559f11c7f63SJim Harris          &(controller->uf_control),
560f11c7f63SJim Harris          frame_index,
561f11c7f63SJim Harris          &smp_response_buffer
562f11c7f63SJim Harris       );
563f11c7f63SJim Harris 
564f11c7f63SJim Harris       scic_word_copy_with_swap(
565f11c7f63SJim Harris          (U32*) (user_smp_buffer + sizeof(SMP_RESPONSE_HEADER_T)),
566f11c7f63SJim Harris          smp_response_buffer,
567f11c7f63SJim Harris          sizeof(SMP_RESPONSE_BODY_T)/sizeof(U32)
568f11c7f63SJim Harris       );
569f11c7f63SJim Harris       if (this_frame_header->function == SMP_FUNCTION_DISCOVER)
570f11c7f63SJim Harris       {
571f11c7f63SJim Harris           SMP_RESPONSE_T * this_smp_response;
572f11c7f63SJim Harris 
573f11c7f63SJim Harris           this_smp_response = (SMP_RESPONSE_T *)user_smp_buffer;
574f11c7f63SJim Harris 
575f11c7f63SJim Harris           // Some expanders only report an attached SATA device, and
576f11c7f63SJim Harris           // not an STP target.  Since the core depends on the STP
577f11c7f63SJim Harris           // target attribute to correctly build I/O, set the bit now
578f11c7f63SJim Harris           // if necessary.
579f11c7f63SJim Harris           if (this_smp_response->response.discover.protocols.u.bits.attached_sata_device
580f11c7f63SJim Harris            && !this_smp_response->response.discover.protocols.u.bits.attached_stp_target)
581f11c7f63SJim Harris           {
582f11c7f63SJim Harris               this_smp_response->response.discover.protocols.u.bits.attached_stp_target = 1;
583f11c7f63SJim Harris 
584f11c7f63SJim Harris               SCIC_LOG_TRACE((
585f11c7f63SJim Harris                   sci_base_object_get_logger(this_request),
586f11c7f63SJim Harris                  SCIC_LOG_OBJECT_SMP_IO_REQUEST,
587f11c7f63SJim Harris                  "scic_sds_smp_request_await_response_frame_handler(0x%x) Found SATA dev, setting STP bit.\n",
588f11c7f63SJim Harris                  this_request
589f11c7f63SJim Harris               ));
590f11c7f63SJim Harris           }
591f11c7f63SJim Harris       }
592f11c7f63SJim Harris 
593f11c7f63SJim Harris      //Don't need to copy to user space. User instead will refer to
594f11c7f63SJim Harris      //core request's response buffer.
595f11c7f63SJim Harris 
596f11c7f63SJim Harris      //copy the smp response to framework smp request's response buffer.
597f11c7f63SJim Harris      //scic_sds_smp_request_copy_response(this_request);
598f11c7f63SJim Harris 
599f11c7f63SJim Harris       scic_sds_request_set_status(
600f11c7f63SJim Harris          this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
601f11c7f63SJim Harris       );
602f11c7f63SJim Harris 
603f11c7f63SJim Harris       sci_base_state_machine_change_state(
604f11c7f63SJim Harris          &this_request->started_substate_machine,
605f11c7f63SJim Harris          SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION
606f11c7f63SJim Harris       );
607f11c7f63SJim Harris    }
608f11c7f63SJim Harris    else
609f11c7f63SJim Harris    {
610f11c7f63SJim Harris       // This was not a response frame why did it get forwarded?
611f11c7f63SJim Harris       SCIC_LOG_ERROR((
612f11c7f63SJim Harris          sci_base_object_get_logger(this_request),
613f11c7f63SJim Harris          SCIC_LOG_OBJECT_SMP_IO_REQUEST,
614f11c7f63SJim Harris          "SCIC SMP Request 0x%08x received unexpected frame %d type 0x%02x\n",
615f11c7f63SJim Harris          this_request, frame_index, this_frame_header->smp_frame_type
616f11c7f63SJim Harris       ));
617f11c7f63SJim Harris 
618f11c7f63SJim Harris      scic_sds_request_set_status(
619f11c7f63SJim Harris         this_request,
620f11c7f63SJim Harris         SCU_TASK_DONE_SMP_FRM_TYPE_ERR,
621f11c7f63SJim Harris         SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
622f11c7f63SJim Harris      );
623f11c7f63SJim Harris 
624f11c7f63SJim Harris      sci_base_state_machine_change_state(
625f11c7f63SJim Harris          &this_request->parent.state_machine,
626f11c7f63SJim Harris          SCI_BASE_REQUEST_STATE_COMPLETED
627f11c7f63SJim Harris       );
628f11c7f63SJim Harris    }
629f11c7f63SJim Harris 
630f11c7f63SJim Harris    scic_sds_controller_release_frame(
631f11c7f63SJim Harris       controller, frame_index
632f11c7f63SJim Harris    );
633f11c7f63SJim Harris 
634f11c7f63SJim Harris    return SCI_SUCCESS;
635f11c7f63SJim Harris }
636f11c7f63SJim Harris 
637f11c7f63SJim Harris 
638f11c7f63SJim Harris /**
639f11c7f63SJim Harris  * @brief This method processes an abnormal TC completion while the SMP
640f11c7f63SJim Harris  *        request is waiting for a response frame.  It decides what
641f11c7f63SJim Harris  *        happened to the IO based on TC completion status.
642f11c7f63SJim Harris  *
643f11c7f63SJim Harris  * @param[in] this_request This parameter specifies the request for which
644f11c7f63SJim Harris  *            the TC completion was received.
645f11c7f63SJim Harris  * @param[in] completion_code This parameter indicates the completion status
646f11c7f63SJim Harris  *            information for the TC.
647f11c7f63SJim Harris  *
648f11c7f63SJim Harris  * @return Indicate if the tc completion handler was successful.
649f11c7f63SJim Harris  * @retval SCI_SUCCESS currently this method always returns success.
650f11c7f63SJim Harris  */
651f11c7f63SJim Harris static
scic_sds_smp_request_await_response_tc_completion_handler(SCIC_SDS_REQUEST_T * this_request,U32 completion_code)652f11c7f63SJim Harris SCI_STATUS scic_sds_smp_request_await_response_tc_completion_handler(
653f11c7f63SJim Harris    SCIC_SDS_REQUEST_T * this_request,
654f11c7f63SJim Harris    U32                  completion_code
655f11c7f63SJim Harris )
656f11c7f63SJim Harris {
657f11c7f63SJim Harris    SCIC_LOG_TRACE((
658f11c7f63SJim Harris       sci_base_object_get_logger(this_request),
659f11c7f63SJim Harris       SCIC_LOG_OBJECT_SMP_IO_REQUEST,
660f11c7f63SJim Harris       "scic_sds_smp_request_await_response_tc_completion_handler(0x%x, 0x%x) enter\n",
661f11c7f63SJim Harris       this_request, completion_code
662f11c7f63SJim Harris    ));
663f11c7f63SJim Harris 
664f11c7f63SJim Harris    switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
665f11c7f63SJim Harris    {
666f11c7f63SJim Harris    case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
667f11c7f63SJim Harris       //In the AWAIT RESPONSE state, any TC completion is unexpected.
668f11c7f63SJim Harris       //but if the TC has success status, we complete the IO anyway.
669f11c7f63SJim Harris       scic_sds_request_set_status(
670f11c7f63SJim Harris          this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
671f11c7f63SJim Harris       );
672f11c7f63SJim Harris 
673f11c7f63SJim Harris       sci_base_state_machine_change_state(
674f11c7f63SJim Harris          &this_request->parent.state_machine,
675f11c7f63SJim Harris          SCI_BASE_REQUEST_STATE_COMPLETED
676f11c7f63SJim Harris       );
677f11c7f63SJim Harris    break;
678f11c7f63SJim Harris 
679f11c7f63SJim Harris    case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_RESP_TO_ERR):
680f11c7f63SJim Harris    case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_UFI_ERR):
681f11c7f63SJim Harris    case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_FRM_TYPE_ERR):
682f11c7f63SJim Harris    case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_SMP_LL_RX_ERR):
683f11c7f63SJim Harris       //These status has been seen in a specific LSI expander, which sometimes
684f11c7f63SJim Harris       //is not able to send smp response within 2 ms. This causes our hardware
685f11c7f63SJim Harris       //break the connection and set TC completion with one of these SMP_XXX_XX_ERR
686f11c7f63SJim Harris       //status. For these type of error, we ask scic user to retry the request.
687f11c7f63SJim Harris       scic_sds_request_set_status(
688f11c7f63SJim Harris          this_request, SCU_TASK_DONE_SMP_RESP_TO_ERR, SCI_FAILURE_RETRY_REQUIRED
689f11c7f63SJim Harris       );
690f11c7f63SJim Harris 
691f11c7f63SJim Harris       sci_base_state_machine_change_state(
692f11c7f63SJim Harris          &this_request->parent.state_machine,
693f11c7f63SJim Harris          SCI_BASE_REQUEST_STATE_COMPLETED
694f11c7f63SJim Harris       );
695f11c7f63SJim Harris    break;
696f11c7f63SJim Harris 
697f11c7f63SJim Harris    default:
698f11c7f63SJim Harris       // All other completion status cause the IO to be complete.  If a NAK
699f11c7f63SJim Harris       // was received, then it is up to the user to retry the request.
700f11c7f63SJim Harris       scic_sds_request_set_status(
701f11c7f63SJim Harris          this_request,
702f11c7f63SJim Harris          SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
703f11c7f63SJim Harris          SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
704f11c7f63SJim Harris       );
705f11c7f63SJim Harris 
706f11c7f63SJim Harris       sci_base_state_machine_change_state(
707f11c7f63SJim Harris          &this_request->parent.state_machine,
708f11c7f63SJim Harris          SCI_BASE_REQUEST_STATE_COMPLETED
709f11c7f63SJim Harris       );
710f11c7f63SJim Harris    break;
711f11c7f63SJim Harris    }
712f11c7f63SJim Harris 
713f11c7f63SJim Harris    return SCI_SUCCESS;
714f11c7f63SJim Harris }
715f11c7f63SJim Harris 
716f11c7f63SJim Harris 
717f11c7f63SJim Harris /**
718f11c7f63SJim Harris  * @brief This method processes the completions transport layer (TL) status
719f11c7f63SJim Harris  *        to determine if the SMP request was sent successfully. If the SMP
720f11c7f63SJim Harris  *        request was sent successfully, then the state for the SMP request
721f11c7f63SJim Harris  *        transits to waiting for a response frame.
722f11c7f63SJim Harris  *
723f11c7f63SJim Harris  * @param[in] this_request This parameter specifies the request for which
724f11c7f63SJim Harris  *            the TC completion was received.
725f11c7f63SJim Harris  * @param[in] completion_code This parameter indicates the completion status
726f11c7f63SJim Harris  *            information for the TC.
727f11c7f63SJim Harris  *
728f11c7f63SJim Harris  * @return Indicate if the tc completion handler was successful.
729f11c7f63SJim Harris  * @retval SCI_SUCCESS currently this method always returns success.
730f11c7f63SJim Harris  */
731f11c7f63SJim Harris static
scic_sds_smp_request_await_tc_completion_tc_completion_handler(SCIC_SDS_REQUEST_T * this_request,U32 completion_code)732f11c7f63SJim Harris SCI_STATUS scic_sds_smp_request_await_tc_completion_tc_completion_handler(
733f11c7f63SJim Harris    SCIC_SDS_REQUEST_T * this_request,
734f11c7f63SJim Harris    U32                  completion_code
735f11c7f63SJim Harris )
736f11c7f63SJim Harris {
737f11c7f63SJim Harris    SCIC_LOG_TRACE((
738f11c7f63SJim Harris       sci_base_object_get_logger(this_request),
739f11c7f63SJim Harris       SCIC_LOG_OBJECT_SMP_IO_REQUEST,
740f11c7f63SJim Harris       "scic_sds_smp_request_await_tc_completion_tc_completion_handler(0x%x, 0x%x) enter\n",
741f11c7f63SJim Harris       this_request, completion_code
742f11c7f63SJim Harris    ));
743f11c7f63SJim Harris 
744f11c7f63SJim Harris    switch (SCU_GET_COMPLETION_TL_STATUS(completion_code))
745f11c7f63SJim Harris    {
746f11c7f63SJim Harris    case SCU_MAKE_COMPLETION_STATUS(SCU_TASK_DONE_GOOD):
747f11c7f63SJim Harris       scic_sds_request_set_status(
748f11c7f63SJim Harris          this_request, SCU_TASK_DONE_GOOD, SCI_SUCCESS
749f11c7f63SJim Harris       );
750f11c7f63SJim Harris 
751f11c7f63SJim Harris       sci_base_state_machine_change_state(
752f11c7f63SJim Harris          &this_request->parent.state_machine,
753f11c7f63SJim Harris          SCI_BASE_REQUEST_STATE_COMPLETED
754f11c7f63SJim Harris       );
755f11c7f63SJim Harris    break;
756f11c7f63SJim Harris 
757f11c7f63SJim Harris    default:
758f11c7f63SJim Harris       // All other completion status cause the IO to be complete.  If a NAK
759f11c7f63SJim Harris       // was received, then it is up to the user to retry the request.
760f11c7f63SJim Harris       scic_sds_request_set_status(
761f11c7f63SJim Harris          this_request,
762f11c7f63SJim Harris          SCU_NORMALIZE_COMPLETION_STATUS(completion_code),
763f11c7f63SJim Harris          SCI_FAILURE_CONTROLLER_SPECIFIC_IO_ERR
764f11c7f63SJim Harris       );
765f11c7f63SJim Harris 
766f11c7f63SJim Harris       sci_base_state_machine_change_state(
767f11c7f63SJim Harris          &this_request->parent.state_machine,
768f11c7f63SJim Harris          SCI_BASE_REQUEST_STATE_COMPLETED
769f11c7f63SJim Harris       );
770f11c7f63SJim Harris    break;
771f11c7f63SJim Harris    }
772f11c7f63SJim Harris 
773f11c7f63SJim Harris    return SCI_SUCCESS;
774f11c7f63SJim Harris }
775f11c7f63SJim Harris 
776f11c7f63SJim Harris 
777f11c7f63SJim Harris SCIC_SDS_IO_REQUEST_STATE_HANDLER_T
778f11c7f63SJim Harris scic_sds_smp_request_started_substate_handler_table
779f11c7f63SJim Harris [SCIC_SDS_SMP_REQUEST_STARTED_MAX_SUBSTATES] =
780f11c7f63SJim Harris {
781f11c7f63SJim Harris    // SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE
782f11c7f63SJim Harris    {
783f11c7f63SJim Harris       {
784f11c7f63SJim Harris          scic_sds_request_default_start_handler,
785f11c7f63SJim Harris          scic_sds_request_started_state_abort_handler,
786f11c7f63SJim Harris          scic_sds_request_default_complete_handler,
787f11c7f63SJim Harris          scic_sds_request_default_destruct_handler
788f11c7f63SJim Harris       },
789f11c7f63SJim Harris       scic_sds_smp_request_await_response_tc_completion_handler,
790f11c7f63SJim Harris       scic_sds_request_default_event_handler,
791f11c7f63SJim Harris       scic_sds_smp_request_await_response_frame_handler
792f11c7f63SJim Harris    },
793f11c7f63SJim Harris    // SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION
794f11c7f63SJim Harris    {
795f11c7f63SJim Harris       {
796f11c7f63SJim Harris          scic_sds_request_default_start_handler,
797f11c7f63SJim Harris          scic_sds_request_started_state_abort_handler,
798f11c7f63SJim Harris          scic_sds_request_default_complete_handler,
799f11c7f63SJim Harris          scic_sds_request_default_destruct_handler
800f11c7f63SJim Harris       },
801f11c7f63SJim Harris       scic_sds_smp_request_await_tc_completion_tc_completion_handler,
802f11c7f63SJim Harris       scic_sds_request_default_event_handler,
803f11c7f63SJim Harris       scic_sds_request_default_frame_handler
804f11c7f63SJim Harris    }
805f11c7f63SJim Harris };
806f11c7f63SJim Harris 
807f11c7f63SJim Harris /**
808f11c7f63SJim Harris  * @brief This method performs the actions required when entering the
809f11c7f63SJim Harris  *        SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_RESPONSE sub-state.
810f11c7f63SJim Harris  *        This includes setting the IO request state handlers for this
811f11c7f63SJim Harris  *        sub-state.
812f11c7f63SJim Harris  *
813f11c7f63SJim Harris  * @param[in]  object This parameter specifies the request object for which
814453130d9SPedro F. Giffuni  *             the sub-state change is occurring.
815f11c7f63SJim Harris  *
816f11c7f63SJim Harris  * @return none.
817f11c7f63SJim Harris  */
818f11c7f63SJim Harris static
scic_sds_smp_request_started_await_response_substate_enter(SCI_BASE_OBJECT_T * object)819f11c7f63SJim Harris void scic_sds_smp_request_started_await_response_substate_enter(
820f11c7f63SJim Harris    SCI_BASE_OBJECT_T *object
821f11c7f63SJim Harris )
822f11c7f63SJim Harris {
823f11c7f63SJim Harris    SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
824f11c7f63SJim Harris 
825f11c7f63SJim Harris    SET_STATE_HANDLER(
826f11c7f63SJim Harris       this_request,
827f11c7f63SJim Harris       scic_sds_smp_request_started_substate_handler_table,
828f11c7f63SJim Harris       SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE
829f11c7f63SJim Harris    );
830f11c7f63SJim Harris }
831f11c7f63SJim Harris 
832f11c7f63SJim Harris /**
833f11c7f63SJim Harris  * @brief This method performs the actions required when entering the
834f11c7f63SJim Harris  *        SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION
835f11c7f63SJim Harris  *        sub-state.  This includes setting the SMP request state handlers for
836f11c7f63SJim Harris  *        this sub-state.
837f11c7f63SJim Harris  *
838f11c7f63SJim Harris  * @param[in]  object This parameter specifies the request object for which
839453130d9SPedro F. Giffuni  *             the sub-state change is occurring.
840f11c7f63SJim Harris  *
841f11c7f63SJim Harris  * @return none.
842f11c7f63SJim Harris  */
843f11c7f63SJim Harris static
scic_sds_smp_request_started_await_tc_completion_substate_enter(SCI_BASE_OBJECT_T * object)844f11c7f63SJim Harris void scic_sds_smp_request_started_await_tc_completion_substate_enter(
845f11c7f63SJim Harris    SCI_BASE_OBJECT_T *object
846f11c7f63SJim Harris )
847f11c7f63SJim Harris {
848f11c7f63SJim Harris    SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)object;
849f11c7f63SJim Harris 
850f11c7f63SJim Harris    SET_STATE_HANDLER(
851f11c7f63SJim Harris       this_request,
852f11c7f63SJim Harris       scic_sds_smp_request_started_substate_handler_table,
853f11c7f63SJim Harris       SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION
854f11c7f63SJim Harris    );
855f11c7f63SJim Harris }
856f11c7f63SJim Harris 
857f11c7f63SJim Harris SCI_BASE_STATE_T scic_sds_smp_request_started_substate_table
858f11c7f63SJim Harris [SCIC_SDS_SMP_REQUEST_STARTED_MAX_SUBSTATES] =
859f11c7f63SJim Harris {
860f11c7f63SJim Harris    {
861f11c7f63SJim Harris       SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_RESPONSE,
862f11c7f63SJim Harris       scic_sds_smp_request_started_await_response_substate_enter,
863f11c7f63SJim Harris       NULL
864f11c7f63SJim Harris    },
865f11c7f63SJim Harris    {
866f11c7f63SJim Harris       SCIC_SDS_SMP_REQUEST_STARTED_SUBSTATE_AWAIT_TC_COMPLETION,
867f11c7f63SJim Harris       scic_sds_smp_request_started_await_tc_completion_substate_enter,
868f11c7f63SJim Harris       NULL
869f11c7f63SJim Harris    }
870f11c7f63SJim Harris };
871f11c7f63SJim Harris 
872f11c7f63SJim Harris 
873