1f11c7f63SJim Harris /*-
2*718cf2ccSPedro F. Giffuni * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0
3*718cf2ccSPedro F. Giffuni *
4f11c7f63SJim Harris * This file is provided under a dual BSD/GPLv2 license. When using or
5f11c7f63SJim Harris * redistributing this file, you may do so under either license.
6f11c7f63SJim Harris *
7f11c7f63SJim Harris * GPL LICENSE SUMMARY
8f11c7f63SJim Harris *
9f11c7f63SJim Harris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
10f11c7f63SJim Harris *
11f11c7f63SJim Harris * This program is free software; you can redistribute it and/or modify
12f11c7f63SJim Harris * it under the terms of version 2 of the GNU General Public License as
13f11c7f63SJim Harris * published by the Free Software Foundation.
14f11c7f63SJim Harris *
15f11c7f63SJim Harris * This program is distributed in the hope that it will be useful, but
16f11c7f63SJim Harris * WITHOUT ANY WARRANTY; without even the implied warranty of
17f11c7f63SJim Harris * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18f11c7f63SJim Harris * General Public License for more details.
19f11c7f63SJim Harris *
20f11c7f63SJim Harris * You should have received a copy of the GNU General Public License
21f11c7f63SJim Harris * along with this program; if not, write to the Free Software
22f11c7f63SJim Harris * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
23f11c7f63SJim Harris * The full GNU General Public License is included in this distribution
24f11c7f63SJim Harris * in the file called LICENSE.GPL.
25f11c7f63SJim Harris *
26f11c7f63SJim Harris * BSD LICENSE
27f11c7f63SJim Harris *
28f11c7f63SJim Harris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved.
29f11c7f63SJim Harris * All rights reserved.
30f11c7f63SJim Harris *
31f11c7f63SJim Harris * Redistribution and use in source and binary forms, with or without
32f11c7f63SJim Harris * modification, are permitted provided that the following conditions
33f11c7f63SJim Harris * are met:
34f11c7f63SJim Harris *
35f11c7f63SJim Harris * * Redistributions of source code must retain the above copyright
36f11c7f63SJim Harris * notice, this list of conditions and the following disclaimer.
37f11c7f63SJim Harris * * Redistributions in binary form must reproduce the above copyright
38f11c7f63SJim Harris * notice, this list of conditions and the following disclaimer in
39f11c7f63SJim Harris * the documentation and/or other materials provided with the
40f11c7f63SJim Harris * distribution.
41f11c7f63SJim Harris *
42f11c7f63SJim Harris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
43f11c7f63SJim Harris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
44f11c7f63SJim Harris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
45f11c7f63SJim Harris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
46f11c7f63SJim Harris * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
47f11c7f63SJim Harris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
48f11c7f63SJim Harris * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
49f11c7f63SJim Harris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
50f11c7f63SJim Harris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
51f11c7f63SJim Harris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
52f11c7f63SJim Harris * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
53f11c7f63SJim Harris */
54f11c7f63SJim Harris
55f11c7f63SJim Harris #include <sys/cdefs.h>
56f11c7f63SJim Harris /**
57f11c7f63SJim Harris * @file
58f11c7f63SJim Harris *
59f11c7f63SJim Harris * @brief This file contains the method implementations for the
60f11c7f63SJim Harris * SCIF_SAS_SMP_IO_REQUEST object. The contents will implement SMP
61f11c7f63SJim Harris * specific functionality.
62f11c7f63SJim Harris */
63f11c7f63SJim Harris
64f11c7f63SJim Harris #include <dev/isci/scil/scif_sas_smp_io_request.h>
65f11c7f63SJim Harris #include <dev/isci/scil/scif_sas_logger.h>
66f11c7f63SJim Harris #include <dev/isci/scil/scif_sas_controller.h>
67f11c7f63SJim Harris #include <dev/isci/scil/sci_controller.h>
68f11c7f63SJim Harris
69f11c7f63SJim Harris #include <dev/isci/scil/sci_status.h>
70f11c7f63SJim Harris #include <dev/isci/scil/scic_io_request.h>
71f11c7f63SJim Harris #include <dev/isci/scil/scic_user_callback.h>
72f11c7f63SJim Harris
73f11c7f63SJim Harris #include <dev/isci/scil/intel_sas.h>
74f11c7f63SJim Harris
75f11c7f63SJim Harris /**
76f11c7f63SJim Harris * @brief This routine is to fill in the space given by core the SMP command
77f11c7f63SJim Harris * frame. Then it calls core's construction.
78f11c7f63SJim Harris *
79f11c7f63SJim Harris * @param[in] fw_io The smp io request to be constructed.
80f11c7f63SJim Harris * @param[in] smp_command The SMP request filled according to SAS spec.
81f11c7f63SJim Harris *
82f11c7f63SJim Harris * @return none
83f11c7f63SJim Harris */
scif_sas_smp_request_construct(SCIF_SAS_REQUEST_T * fw_request,SMP_REQUEST_T * smp_command)84f11c7f63SJim Harris void scif_sas_smp_request_construct(
85f11c7f63SJim Harris SCIF_SAS_REQUEST_T * fw_request,
86f11c7f63SJim Harris SMP_REQUEST_T * smp_command
87f11c7f63SJim Harris )
88f11c7f63SJim Harris {
89f11c7f63SJim Harris void * command_iu_address =
90f11c7f63SJim Harris scic_io_request_get_command_iu_address(fw_request->core_object);
91f11c7f63SJim Harris
92f11c7f63SJim Harris //copy the smp_command to the address;
93f11c7f63SJim Harris memcpy( (char*) command_iu_address,
94f11c7f63SJim Harris smp_command,
95f11c7f63SJim Harris sizeof(SMP_REQUEST_T)
96f11c7f63SJim Harris );
97f11c7f63SJim Harris
98f11c7f63SJim Harris scic_io_request_construct_smp(fw_request->core_object);
99f11c7f63SJim Harris
100f11c7f63SJim Harris fw_request->protocol_complete_handler
101f11c7f63SJim Harris = NULL;
102f11c7f63SJim Harris }
103f11c7f63SJim Harris
104f11c7f63SJim Harris /**
105f11c7f63SJim Harris * @brief This method will perform all of the construction common to all
106f11c7f63SJim Harris * SMP requests (e.g. filling in the frame type, zero-out memory,
107f11c7f63SJim Harris * etc.).
108f11c7f63SJim Harris *
109f11c7f63SJim Harris * @param[out] smp_request This parameter specifies the SMP request
110f11c7f63SJim Harris * structure containing the SMP request to be sent to the
111f11c7f63SJim Harris * SMP target.
112f11c7f63SJim Harris * @param[in] smp_function This parameter specifies the SMP function to
113f11c7f63SJim Harris * sent.
114f11c7f63SJim Harris * @param[in] smp_response_length This parameter specifies the length of
115f11c7f63SJim Harris * the response (in DWORDs) that will be returned for this
116f11c7f63SJim Harris * SMP request.
117f11c7f63SJim Harris * @param[in] smp_request_length This parameter specifies the length of
118f11c7f63SJim Harris * the request (in DWORDs) that will be sent.
119f11c7f63SJim Harris */
120f11c7f63SJim Harris static
scif_sas_smp_protocol_request_construct(SMP_REQUEST_T * smp_request,U8 smp_function,U8 smp_response_length,U8 smp_request_length)121f11c7f63SJim Harris void scif_sas_smp_protocol_request_construct(
122f11c7f63SJim Harris SMP_REQUEST_T * smp_request,
123f11c7f63SJim Harris U8 smp_function,
124f11c7f63SJim Harris U8 smp_response_length,
125f11c7f63SJim Harris U8 smp_request_length
126f11c7f63SJim Harris )
127f11c7f63SJim Harris {
128f11c7f63SJim Harris memset((char*)smp_request, 0, sizeof(SMP_REQUEST_T));
129f11c7f63SJim Harris
130f11c7f63SJim Harris smp_request->header.smp_frame_type = SMP_FRAME_TYPE_REQUEST;
131f11c7f63SJim Harris smp_request->header.function = smp_function;
132f11c7f63SJim Harris smp_request->header.allocated_response_length = smp_response_length;
133f11c7f63SJim Harris smp_request->header.request_length = smp_request_length;
134f11c7f63SJim Harris }
135f11c7f63SJim Harris
136f11c7f63SJim Harris
137f11c7f63SJim Harris /**
138f11c7f63SJim Harris * @brief This method will allocate the internal IO request object and
139f11c7f63SJim Harris * construct its contents based upon the supplied SMP request.
140f11c7f63SJim Harris *
141f11c7f63SJim Harris * @param[in] fw_controller This parameter specifies the controller object
142f11c7f63SJim Harris * from which to allocate the internal IO request.
143f11c7f63SJim Harris * @param[in] fw_device This parameter specifies the remote device for
144f11c7f63SJim Harris * which the internal IO request is destined.
145f11c7f63SJim Harris * @param[in] smp_request This parameter specifies the SMP request contents
146f11c7f63SJim Harris * to be sent to the SMP target.
147f11c7f63SJim Harris *
148f11c7f63SJim Harris * @return void * The address of built scif sas smp request.
149f11c7f63SJim Harris */
150f11c7f63SJim Harris static
scif_sas_smp_request_build(SCIF_SAS_CONTROLLER_T * fw_controller,SCIF_SAS_REMOTE_DEVICE_T * fw_device,SMP_REQUEST_T * smp_request,void * external_request_object,void * external_memory)151f11c7f63SJim Harris void * scif_sas_smp_request_build(
152f11c7f63SJim Harris SCIF_SAS_CONTROLLER_T * fw_controller,
153f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * fw_device,
154f11c7f63SJim Harris SMP_REQUEST_T * smp_request,
155f11c7f63SJim Harris void * external_request_object,
156f11c7f63SJim Harris void * external_memory
157f11c7f63SJim Harris )
158f11c7f63SJim Harris {
159f11c7f63SJim Harris if (external_memory != NULL && external_request_object != NULL)
160f11c7f63SJim Harris {
161f11c7f63SJim Harris scif_sas_io_request_construct_smp(
162f11c7f63SJim Harris fw_controller,
163f11c7f63SJim Harris fw_device,
164f11c7f63SJim Harris external_memory,
165f11c7f63SJim Harris (char *)external_memory + sizeof(SCIF_SAS_IO_REQUEST_T),
166f11c7f63SJim Harris SCI_CONTROLLER_INVALID_IO_TAG,
167f11c7f63SJim Harris smp_request,
168f11c7f63SJim Harris external_request_object
169f11c7f63SJim Harris );
170f11c7f63SJim Harris
171f11c7f63SJim Harris return external_memory;
172f11c7f63SJim Harris }
173f11c7f63SJim Harris else
174f11c7f63SJim Harris {
175f11c7f63SJim Harris void * internal_io_memory;
176f11c7f63SJim Harris internal_io_memory = scif_sas_controller_allocate_internal_request(fw_controller);
177f11c7f63SJim Harris ASSERT(internal_io_memory != NULL);
178f11c7f63SJim Harris
179f11c7f63SJim Harris if (internal_io_memory != NULL)
180f11c7f63SJim Harris {
181f11c7f63SJim Harris //construct, only when we got valid io memory.
182f11c7f63SJim Harris scif_sas_internal_io_request_construct_smp(
183f11c7f63SJim Harris fw_controller,
184f11c7f63SJim Harris fw_device,
185f11c7f63SJim Harris internal_io_memory,
186f11c7f63SJim Harris SCI_CONTROLLER_INVALID_IO_TAG,
187f11c7f63SJim Harris smp_request
188f11c7f63SJim Harris );
189f11c7f63SJim Harris }
190f11c7f63SJim Harris else
191f11c7f63SJim Harris {
192f11c7f63SJim Harris SCIF_LOG_ERROR((
193f11c7f63SJim Harris sci_base_object_get_logger(fw_controller),
194f11c7f63SJim Harris SCIF_LOG_OBJECT_IO_REQUEST,
195f11c7f63SJim Harris "scif_sas_smp_request_build, no memory available!\n"
196f11c7f63SJim Harris ));
197f11c7f63SJim Harris }
198f11c7f63SJim Harris
199f11c7f63SJim Harris return internal_io_memory;
200f11c7f63SJim Harris }
201f11c7f63SJim Harris }
202f11c7f63SJim Harris
203f11c7f63SJim Harris /**
204f11c7f63SJim Harris * @brief construct a smp Report Genernal command to the fw_device.
205f11c7f63SJim Harris *
206f11c7f63SJim Harris * @param[in] fw_controller The framework controller object.
207f11c7f63SJim Harris * @param[in] fw_device the framework device that the REPORT GENERAL command
208f11c7f63SJim Harris * targets to.
209f11c7f63SJim Harris *
210f11c7f63SJim Harris * @return void * address to the built scif sas smp request.
211f11c7f63SJim Harris */
scif_sas_smp_request_construct_report_general(SCIF_SAS_CONTROLLER_T * fw_controller,SCIF_SAS_REMOTE_DEVICE_T * fw_device)212f11c7f63SJim Harris void * scif_sas_smp_request_construct_report_general(
213f11c7f63SJim Harris SCIF_SAS_CONTROLLER_T * fw_controller,
214f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * fw_device
215f11c7f63SJim Harris )
216f11c7f63SJim Harris {
217f11c7f63SJim Harris SMP_REQUEST_T smp_report_general;
218f11c7f63SJim Harris
219f11c7f63SJim Harris // Build the REPORT GENERAL request.
220f11c7f63SJim Harris scif_sas_smp_protocol_request_construct(
221f11c7f63SJim Harris &smp_report_general,
222f11c7f63SJim Harris SMP_FUNCTION_REPORT_GENERAL,
223f11c7f63SJim Harris sizeof(SMP_RESPONSE_REPORT_GENERAL_T) / sizeof(U32),
224f11c7f63SJim Harris 0
225f11c7f63SJim Harris );
226f11c7f63SJim Harris
227f11c7f63SJim Harris smp_report_general.request.report_general.crc = 0;
228f11c7f63SJim Harris
229f11c7f63SJim Harris SCIF_LOG_INFO((
230f11c7f63SJim Harris sci_base_object_get_logger(fw_device),
231f11c7f63SJim Harris SCIF_LOG_OBJECT_IO_REQUEST | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
232f11c7f63SJim Harris "SMP REPORT GENERAL - Device:0x%x\n",
233f11c7f63SJim Harris fw_device
234f11c7f63SJim Harris ));
235f11c7f63SJim Harris
236f11c7f63SJim Harris return scif_sas_smp_request_build(
237f11c7f63SJim Harris fw_controller, fw_device, &smp_report_general, NULL, NULL);
238f11c7f63SJim Harris }
239f11c7f63SJim Harris
240f11c7f63SJim Harris /**
241f11c7f63SJim Harris * @brief construct a SMP Report Manufacturer Info request to the fw_device.
242f11c7f63SJim Harris *
243f11c7f63SJim Harris * @param[in] fw_controller The framework controller object.
244f11c7f63SJim Harris * @param[in] fw_device the framework device that the REPORT MANUFACTURER
245f11c7f63SJim Harris * INFO targets to.
246f11c7f63SJim Harris *
247f11c7f63SJim Harris * @return void * address to the built scif sas smp request.
248f11c7f63SJim Harris */
scif_sas_smp_request_construct_report_manufacturer_info(SCIF_SAS_CONTROLLER_T * fw_controller,SCIF_SAS_REMOTE_DEVICE_T * fw_device)249f11c7f63SJim Harris void * scif_sas_smp_request_construct_report_manufacturer_info(
250f11c7f63SJim Harris SCIF_SAS_CONTROLLER_T * fw_controller,
251f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * fw_device
252f11c7f63SJim Harris )
253f11c7f63SJim Harris {
254f11c7f63SJim Harris SMP_REQUEST_T smp_report_manufacturer_info;
255f11c7f63SJim Harris
256f11c7f63SJim Harris scif_sas_smp_protocol_request_construct(
257f11c7f63SJim Harris &smp_report_manufacturer_info,
258f11c7f63SJim Harris SMP_FUNCTION_REPORT_MANUFACTURER_INFORMATION,
259f11c7f63SJim Harris sizeof(SMP_RESPONSE_REPORT_MANUFACTURER_INFORMATION_T) / sizeof(U32),
260f11c7f63SJim Harris 0
261f11c7f63SJim Harris );
262f11c7f63SJim Harris
263f11c7f63SJim Harris smp_report_manufacturer_info.request.report_general.crc = 0;
264f11c7f63SJim Harris
265f11c7f63SJim Harris SCIF_LOG_INFO((
266f11c7f63SJim Harris sci_base_object_get_logger(fw_device),
267f11c7f63SJim Harris SCIF_LOG_OBJECT_IO_REQUEST | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
268f11c7f63SJim Harris "SMP REPORT MANUFACTURER_INFO - Device:0x%x\n",
269f11c7f63SJim Harris fw_device
270f11c7f63SJim Harris ));
271f11c7f63SJim Harris
272f11c7f63SJim Harris return scif_sas_smp_request_build(
273f11c7f63SJim Harris fw_controller, fw_device, &smp_report_manufacturer_info, NULL, NULL
274f11c7f63SJim Harris );
275f11c7f63SJim Harris }
276f11c7f63SJim Harris
277f11c7f63SJim Harris /**
278f11c7f63SJim Harris * @brief construct a smp Discover command to the fw_device.
279f11c7f63SJim Harris * @param[in] fw_controller The framework controller object.
280f11c7f63SJim Harris * @param[in] fw_device the framework smp device that DISCOVER command targets
281f11c7f63SJim Harris * to.
282f11c7f63SJim Harris * @param[in] phy_identifier The phy index the DISCOVER command targets to.
283f11c7f63SJim Harris *
284f11c7f63SJim Harris * @return void * address to the built scif sas smp request.
285f11c7f63SJim Harris */
scif_sas_smp_request_construct_discover(SCIF_SAS_CONTROLLER_T * fw_controller,SCIF_SAS_REMOTE_DEVICE_T * fw_device,U8 phy_identifier,void * external_request_object,void * external_memory)286f11c7f63SJim Harris void * scif_sas_smp_request_construct_discover(
287f11c7f63SJim Harris SCIF_SAS_CONTROLLER_T * fw_controller,
288f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * fw_device,
289f11c7f63SJim Harris U8 phy_identifier,
290f11c7f63SJim Harris void * external_request_object,
291f11c7f63SJim Harris void * external_memory
292f11c7f63SJim Harris )
293f11c7f63SJim Harris {
294f11c7f63SJim Harris SMP_REQUEST_T smp_discover;
295f11c7f63SJim Harris
296f11c7f63SJim Harris scif_sas_smp_protocol_request_construct(
297f11c7f63SJim Harris &smp_discover,
298f11c7f63SJim Harris SMP_FUNCTION_DISCOVER,
299f11c7f63SJim Harris sizeof(SMP_RESPONSE_DISCOVER_T) / sizeof(U32),
300f11c7f63SJim Harris sizeof(SMP_REQUEST_PHY_IDENTIFIER_T) / sizeof(U32)
301f11c7f63SJim Harris );
302f11c7f63SJim Harris
303f11c7f63SJim Harris smp_discover.request.discover.phy_identifier = phy_identifier;
304f11c7f63SJim Harris
305f11c7f63SJim Harris SCIF_LOG_INFO((
306f11c7f63SJim Harris sci_base_object_get_logger(fw_device),
307f11c7f63SJim Harris SCIF_LOG_OBJECT_IO_REQUEST | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
308f11c7f63SJim Harris "SMP DISCOVER - Device:0x%x PhyId:0x%x\n",
309f11c7f63SJim Harris fw_device, phy_identifier
310f11c7f63SJim Harris ));
311f11c7f63SJim Harris
312f11c7f63SJim Harris return scif_sas_smp_request_build(
313f11c7f63SJim Harris fw_controller, fw_device, &smp_discover,
314f11c7f63SJim Harris external_request_object, external_memory
315f11c7f63SJim Harris );
316f11c7f63SJim Harris }
317f11c7f63SJim Harris
318f11c7f63SJim Harris
319f11c7f63SJim Harris /**
320f11c7f63SJim Harris * @brief construct a smp REPORT PHY SATA command to the fw_device.
321f11c7f63SJim Harris * @param[in] fw_controller The framework controller object.
322f11c7f63SJim Harris * @param[in] fw_device the framework smp device that DISCOVER command targets
323f11c7f63SJim Harris * to.
324f11c7f63SJim Harris * @param[in] phy_identifier The phy index the DISCOVER command targets to.
325f11c7f63SJim Harris *
326f11c7f63SJim Harris * @return void * address to the built scif sas smp request.
327f11c7f63SJim Harris */
scif_sas_smp_request_construct_report_phy_sata(SCIF_SAS_CONTROLLER_T * fw_controller,SCIF_SAS_REMOTE_DEVICE_T * fw_device,U8 phy_identifier)328f11c7f63SJim Harris void * scif_sas_smp_request_construct_report_phy_sata(
329f11c7f63SJim Harris SCIF_SAS_CONTROLLER_T * fw_controller,
330f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * fw_device,
331f11c7f63SJim Harris U8 phy_identifier
332f11c7f63SJim Harris )
333f11c7f63SJim Harris {
334f11c7f63SJim Harris SMP_REQUEST_T report_phy_sata;
335f11c7f63SJim Harris
336f11c7f63SJim Harris scif_sas_smp_protocol_request_construct(
337f11c7f63SJim Harris &report_phy_sata,
338f11c7f63SJim Harris SMP_FUNCTION_REPORT_PHY_SATA,
339f11c7f63SJim Harris sizeof(SMP_RESPONSE_REPORT_PHY_SATA_T) / sizeof(U32),
340f11c7f63SJim Harris sizeof(SMP_REQUEST_PHY_IDENTIFIER_T) / sizeof(U32)
341f11c7f63SJim Harris );
342f11c7f63SJim Harris
343f11c7f63SJim Harris report_phy_sata.request.report_phy_sata.phy_identifier = phy_identifier;
344f11c7f63SJim Harris
345f11c7f63SJim Harris SCIF_LOG_INFO((
346f11c7f63SJim Harris sci_base_object_get_logger(fw_device),
347f11c7f63SJim Harris SCIF_LOG_OBJECT_IO_REQUEST | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
348f11c7f63SJim Harris "SMP REPORT PHY SATA - Device:0x%x PhyId:0x%x\n",
349f11c7f63SJim Harris fw_device, phy_identifier
350f11c7f63SJim Harris ));
351f11c7f63SJim Harris
352f11c7f63SJim Harris return scif_sas_smp_request_build(
353f11c7f63SJim Harris fw_controller, fw_device, &report_phy_sata, NULL, NULL);
354f11c7f63SJim Harris }
355f11c7f63SJim Harris
356f11c7f63SJim Harris
357f11c7f63SJim Harris /**
358f11c7f63SJim Harris * @brief construct a smp REPORT PHY SATA command to the fw_device.
359f11c7f63SJim Harris * @param[in] fw_controller The framework controller object.
360f11c7f63SJim Harris * @param[in] fw_device the framework smp device that PHY CONTROL command
361f11c7f63SJim Harris * targets to.
362f11c7f63SJim Harris * @param[in] phy_identifier The phy index the DISCOVER command targets to.
363f11c7f63SJim Harris *
364f11c7f63SJim Harris * @return void * address to the built scif sas smp request.
365f11c7f63SJim Harris */
scif_sas_smp_request_construct_phy_control(SCIF_SAS_CONTROLLER_T * fw_controller,SCIF_SAS_REMOTE_DEVICE_T * fw_device,U8 phy_operation,U8 phy_identifier,void * external_request_object,void * external_memory)366f11c7f63SJim Harris void * scif_sas_smp_request_construct_phy_control(
367f11c7f63SJim Harris SCIF_SAS_CONTROLLER_T * fw_controller,
368f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * fw_device,
369f11c7f63SJim Harris U8 phy_operation,
370f11c7f63SJim Harris U8 phy_identifier,
371f11c7f63SJim Harris void * external_request_object,
372f11c7f63SJim Harris void * external_memory
373f11c7f63SJim Harris )
374f11c7f63SJim Harris {
375f11c7f63SJim Harris SMP_REQUEST_T phy_control;
376f11c7f63SJim Harris
377f11c7f63SJim Harris scif_sas_smp_protocol_request_construct(
378f11c7f63SJim Harris &phy_control,
379f11c7f63SJim Harris SMP_FUNCTION_PHY_CONTROL,
380f11c7f63SJim Harris 0,
381f11c7f63SJim Harris sizeof(SMP_REQUEST_PHY_CONTROL_T) / sizeof(U32)
382f11c7f63SJim Harris );
383f11c7f63SJim Harris
384f11c7f63SJim Harris phy_control.request.phy_control.phy_operation = phy_operation;
385f11c7f63SJim Harris phy_control.request.phy_control.phy_identifier = phy_identifier;
386f11c7f63SJim Harris
387f11c7f63SJim Harris return scif_sas_smp_request_build(
388f11c7f63SJim Harris fw_controller, fw_device, &phy_control,
389f11c7f63SJim Harris external_request_object, external_memory
390f11c7f63SJim Harris );
391f11c7f63SJim Harris }
392f11c7f63SJim Harris
393f11c7f63SJim Harris
394f11c7f63SJim Harris /**
395f11c7f63SJim Harris * @brief construct a smp CONFIG ROUTE INFO command to the fw_device.
396f11c7f63SJim Harris *
397f11c7f63SJim Harris * @param[in] fw_controller The framework controller object.
398f11c7f63SJim Harris * @param[in] fw_device the framework smp device that PHY CONTROL command
399f11c7f63SJim Harris * targets to.
400f11c7f63SJim Harris * @param[in] phy_id The phy, whose route entry at route_index is to be configured.
401f11c7f63SJim Harris * @param[in] route_index The index of a phy's route entry that is to be configured.
402f11c7f63SJim Harris * @param[in] destination_sas_address A sas address for an route table entry
403f11c7f63SJim Harris *
404f11c7f63SJim Harris * @return void * address to the built scif sas smp request.
405f11c7f63SJim Harris */
scif_sas_smp_request_construct_config_route_info(struct SCIF_SAS_CONTROLLER * fw_controller,struct SCIF_SAS_REMOTE_DEVICE * fw_device,U8 phy_id,U16 route_index,SCI_SAS_ADDRESS_T destination_sas_address,BOOL disable_expander_route_entry)406f11c7f63SJim Harris void * scif_sas_smp_request_construct_config_route_info(
407f11c7f63SJim Harris struct SCIF_SAS_CONTROLLER * fw_controller,
408f11c7f63SJim Harris struct SCIF_SAS_REMOTE_DEVICE * fw_device,
409f11c7f63SJim Harris U8 phy_id,
410f11c7f63SJim Harris U16 route_index,
411f11c7f63SJim Harris SCI_SAS_ADDRESS_T destination_sas_address,
412f11c7f63SJim Harris BOOL disable_expander_route_entry
413f11c7f63SJim Harris )
414f11c7f63SJim Harris {
415f11c7f63SJim Harris SMP_REQUEST_T config_route_info;
416f11c7f63SJim Harris
417f11c7f63SJim Harris scif_sas_smp_protocol_request_construct(
418f11c7f63SJim Harris &config_route_info,
419f11c7f63SJim Harris SMP_FUNCTION_CONFIGURE_ROUTE_INFORMATION,
420f11c7f63SJim Harris 0,
421f11c7f63SJim Harris sizeof(SMP_REQUEST_CONFIGURE_ROUTE_INFORMATION_T) / sizeof(U32)
422f11c7f63SJim Harris );
423f11c7f63SJim Harris
424f11c7f63SJim Harris config_route_info.request.configure_route_information.phy_identifier = phy_id;
425f11c7f63SJim Harris config_route_info.request.configure_route_information.expander_route_index_high =
426f11c7f63SJim Harris ((route_index & 0xff00) >> 8);
427f11c7f63SJim Harris config_route_info.request.configure_route_information.expander_route_index =
428f11c7f63SJim Harris route_index & 0xff;
429f11c7f63SJim Harris config_route_info.request.configure_route_information.routed_sas_address[0] =
430f11c7f63SJim Harris destination_sas_address.high;
431f11c7f63SJim Harris config_route_info.request.configure_route_information.routed_sas_address[1] =
432f11c7f63SJim Harris destination_sas_address.low;
433f11c7f63SJim Harris
434f11c7f63SJim Harris if (disable_expander_route_entry == TRUE)
435f11c7f63SJim Harris config_route_info.request.configure_route_information.disable_route_entry = 1;
436f11c7f63SJim Harris
437f11c7f63SJim Harris return scif_sas_smp_request_build(
438f11c7f63SJim Harris fw_controller, fw_device, &config_route_info,
439f11c7f63SJim Harris NULL, NULL
440f11c7f63SJim Harris );
441f11c7f63SJim Harris }
442f11c7f63SJim Harris
443f11c7f63SJim Harris /**
444f11c7f63SJim Harris * @brief This method retry the internal smp request.
445f11c7f63SJim Harris *
446f11c7f63SJim Harris * @param[in] fw_device This parameter specifies the remote device for
447f11c7f63SJim Harris * which the internal IO request is destined.
448f11c7f63SJim Harris * @param[in] retry_count This parameter specifies how many times the
449f11c7f63SJim Harris * old smp request has been retried.
450f11c7f63SJim Harris *
451f11c7f63SJim Harris * @return none.
452f11c7f63SJim Harris */
scif_sas_smp_internal_request_retry(SCIF_SAS_REMOTE_DEVICE_T * fw_device)453f11c7f63SJim Harris SCI_STATUS scif_sas_smp_internal_request_retry(
454f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * fw_device
455f11c7f63SJim Harris )
456f11c7f63SJim Harris {
457f11c7f63SJim Harris SCIF_SAS_CONTROLLER_T * fw_controller;
458f11c7f63SJim Harris SCIF_SAS_IO_REQUEST_T * new_io;
459f11c7f63SJim Harris void * new_request_memory = NULL;
460f11c7f63SJim Harris U8 retry_count = fw_device->protocol_device.smp_device.io_retry_count;
461f11c7f63SJim Harris
462f11c7f63SJim Harris SCIF_LOG_TRACE((
463f11c7f63SJim Harris sci_base_object_get_logger(fw_device),
464f11c7f63SJim Harris SCIF_LOG_OBJECT_IO_REQUEST | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
465f11c7f63SJim Harris "scif_sas_smp_internal_request_retry(0x%x, 0x%x) time %d!\n",
466f11c7f63SJim Harris fw_device, retry_count
467f11c7f63SJim Harris ));
468f11c7f63SJim Harris
469f11c7f63SJim Harris fw_controller = fw_device->domain->controller;
470f11c7f63SJim Harris
471f11c7f63SJim Harris switch (fw_device->protocol_device.smp_device.current_smp_request)
472f11c7f63SJim Harris {
473f11c7f63SJim Harris case SMP_FUNCTION_REPORT_GENERAL:
474f11c7f63SJim Harris new_request_memory = scif_sas_smp_request_construct_report_general(
475f11c7f63SJim Harris fw_controller, fw_device
476f11c7f63SJim Harris );
477f11c7f63SJim Harris break;
478f11c7f63SJim Harris
479f11c7f63SJim Harris case SMP_FUNCTION_DISCOVER:
480f11c7f63SJim Harris //We are retrying an internal io. So we are going to allocate
481f11c7f63SJim Harris //a new memory from internal io memory pool.
482f11c7f63SJim Harris new_request_memory = scif_sas_smp_request_construct_discover(
483f11c7f63SJim Harris fw_controller, fw_device,
484f11c7f63SJim Harris fw_device->protocol_device.smp_device.current_activity_phy_index,
485f11c7f63SJim Harris NULL, NULL
486f11c7f63SJim Harris );
487f11c7f63SJim Harris
488f11c7f63SJim Harris break;
489f11c7f63SJim Harris
490f11c7f63SJim Harris case SMP_FUNCTION_REPORT_PHY_SATA:
491f11c7f63SJim Harris new_request_memory = scif_sas_smp_request_construct_report_phy_sata(
492f11c7f63SJim Harris fw_controller, fw_device,
493f11c7f63SJim Harris fw_device->protocol_device.smp_device.current_activity_phy_index
494f11c7f63SJim Harris );
495f11c7f63SJim Harris break;
496f11c7f63SJim Harris
497f11c7f63SJim Harris default:
498f11c7f63SJim Harris //unsupported case, TBD
499f11c7f63SJim Harris break;
500f11c7f63SJim Harris } //end of switch
501f11c7f63SJim Harris
502f11c7f63SJim Harris if (new_request_memory != NULL)
503f11c7f63SJim Harris {
504f11c7f63SJim Harris //set the retry count to new built smp request.
505f11c7f63SJim Harris new_io = (SCIF_SAS_IO_REQUEST_T *) new_request_memory;
506f11c7f63SJim Harris new_io->retry_count = ++retry_count;
507f11c7f63SJim Harris
508f11c7f63SJim Harris //need to schedule the DPC here.
509f11c7f63SJim Harris scif_cb_start_internal_io_task_schedule(
510f11c7f63SJim Harris fw_controller,
511f11c7f63SJim Harris scif_sas_controller_start_high_priority_io,
512f11c7f63SJim Harris fw_controller
513f11c7f63SJim Harris );
514f11c7f63SJim Harris
515f11c7f63SJim Harris return SCI_SUCCESS;
516f11c7f63SJim Harris }
517f11c7f63SJim Harris else
518f11c7f63SJim Harris return SCI_FAILURE_INSUFFICIENT_RESOURCES;
519f11c7f63SJim Harris
520f11c7f63SJim Harris }
521f11c7f63SJim Harris
522f11c7f63SJim Harris /**
523f11c7f63SJim Harris * @brief This method retry the external smp request.
524f11c7f63SJim Harris *
525f11c7f63SJim Harris * @param[in] fw_device This parameter specifies the remote device for
526f11c7f63SJim Harris * which the internal IO request is destined.
527f11c7f63SJim Harris * @param[in] old_internal_io This parameter specifies the old smp request to be
528f11c7f63SJim Harris * retried.
529f11c7f63SJim Harris *
530f11c7f63SJim Harris * @return none.
531f11c7f63SJim Harris */
scif_sas_smp_external_request_retry(SCIF_SAS_IO_REQUEST_T * old_io)532f11c7f63SJim Harris SCI_STATUS scif_sas_smp_external_request_retry(
533f11c7f63SJim Harris SCIF_SAS_IO_REQUEST_T * old_io
534f11c7f63SJim Harris )
535f11c7f63SJim Harris {
536f11c7f63SJim Harris SCIF_SAS_REMOTE_DEVICE_T * fw_device = old_io->parent.device;
537f11c7f63SJim Harris SCIF_SAS_CONTROLLER_T * fw_controller;
538f11c7f63SJim Harris SCIF_SAS_IO_REQUEST_T * new_io;
539f11c7f63SJim Harris void * new_request_memory = NULL;
540f11c7f63SJim Harris U8 retry_count = old_io->retry_count;
541f11c7f63SJim Harris
542f11c7f63SJim Harris SCIF_LOG_TRACE((
543f11c7f63SJim Harris sci_base_object_get_logger(fw_device),
544f11c7f63SJim Harris SCIF_LOG_OBJECT_IO_REQUEST | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY,
545f11c7f63SJim Harris "scif_sas_smp_external_request_retry(0x%x) time %d!\n",
546f11c7f63SJim Harris old_io
547f11c7f63SJim Harris ));
548f11c7f63SJim Harris
549f11c7f63SJim Harris fw_controller = fw_device->domain->controller;
550f11c7f63SJim Harris
551f11c7f63SJim Harris // Before we construct new io using the same memory, we need to
552f11c7f63SJim Harris // remove the IO from the list of outstanding requests on the domain
553f11c7f63SJim Harris // so that we don't damage the domain's fast list of request.
554f11c7f63SJim Harris sci_fast_list_remove_element(&old_io->parent.list_element);
555f11c7f63SJim Harris
556f11c7f63SJim Harris switch (fw_device->protocol_device.smp_device.current_smp_request)
557f11c7f63SJim Harris {
558f11c7f63SJim Harris case SMP_FUNCTION_DISCOVER:
559f11c7f63SJim Harris //we are retrying an external io, we are going to reuse the
560f11c7f63SJim Harris //old io's memory. new_request_memory is same as old_io.
561f11c7f63SJim Harris new_request_memory = scif_sas_smp_request_construct_discover(
562f11c7f63SJim Harris fw_controller, fw_device,
563f11c7f63SJim Harris fw_device->protocol_device.smp_device.current_activity_phy_index,
564f11c7f63SJim Harris (void *)sci_object_get_association(old_io),
565f11c7f63SJim Harris (void *)old_io
566f11c7f63SJim Harris );
567f11c7f63SJim Harris
568f11c7f63SJim Harris break;
569f11c7f63SJim Harris
570f11c7f63SJim Harris case SMP_FUNCTION_PHY_CONTROL:
571f11c7f63SJim Harris //Phy Control command always uses external io memory.
572f11c7f63SJim Harris new_request_memory = scif_sas_smp_request_construct_phy_control(
573f11c7f63SJim Harris fw_controller, fw_device, PHY_OPERATION_HARD_RESET,
574f11c7f63SJim Harris fw_device->protocol_device.smp_device.current_activity_phy_index,
575f11c7f63SJim Harris (void *)sci_object_get_association(old_io),
576f11c7f63SJim Harris (void *)old_io
577f11c7f63SJim Harris );
578f11c7f63SJim Harris
579f11c7f63SJim Harris break;
580f11c7f63SJim Harris
581f11c7f63SJim Harris default:
582f11c7f63SJim Harris //unsupported case, TBD
5832d57bb86SJim Harris return SCI_FAILURE;
584f11c7f63SJim Harris } //end of switch
585f11c7f63SJim Harris
586f11c7f63SJim Harris //set the retry count to new built smp request.
587f11c7f63SJim Harris new_io = (SCIF_SAS_IO_REQUEST_T *) new_request_memory;
588f11c7f63SJim Harris new_io->retry_count = ++retry_count;
589f11c7f63SJim Harris
590f11c7f63SJim Harris //put into the high priority queue.
591f11c7f63SJim Harris sci_pool_put(fw_controller->hprq.pool, (POINTER_UINT) new_request_memory);
592f11c7f63SJim Harris
593f11c7f63SJim Harris //schedule the DPC to start new io.
594f11c7f63SJim Harris scif_cb_start_internal_io_task_schedule(
595f11c7f63SJim Harris fw_controller, scif_sas_controller_start_high_priority_io, fw_controller
596f11c7f63SJim Harris );
597f11c7f63SJim Harris
598f11c7f63SJim Harris return SCI_SUCCESS;
599f11c7f63SJim Harris }
600f11c7f63SJim Harris
601