1230557Sjimharris/*- 2230557Sjimharris * This file is provided under a dual BSD/GPLv2 license. When using or 3230557Sjimharris * redistributing this file, you may do so under either license. 4230557Sjimharris * 5230557Sjimharris * GPL LICENSE SUMMARY 6230557Sjimharris * 7230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 8230557Sjimharris * 9230557Sjimharris * This program is free software; you can redistribute it and/or modify 10230557Sjimharris * it under the terms of version 2 of the GNU General Public License as 11230557Sjimharris * published by the Free Software Foundation. 12230557Sjimharris * 13230557Sjimharris * This program is distributed in the hope that it will be useful, but 14230557Sjimharris * WITHOUT ANY WARRANTY; without even the implied warranty of 15230557Sjimharris * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16230557Sjimharris * General Public License for more details. 17230557Sjimharris * 18230557Sjimharris * You should have received a copy of the GNU General Public License 19230557Sjimharris * along with this program; if not, write to the Free Software 20230557Sjimharris * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 21230557Sjimharris * The full GNU General Public License is included in this distribution 22230557Sjimharris * in the file called LICENSE.GPL. 23230557Sjimharris * 24230557Sjimharris * BSD LICENSE 25230557Sjimharris * 26230557Sjimharris * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 27230557Sjimharris * All rights reserved. 28230557Sjimharris * 29230557Sjimharris * Redistribution and use in source and binary forms, with or without 30230557Sjimharris * modification, are permitted provided that the following conditions 31230557Sjimharris * are met: 32230557Sjimharris * 33230557Sjimharris * * Redistributions of source code must retain the above copyright 34230557Sjimharris * notice, this list of conditions and the following disclaimer. 35230557Sjimharris * * Redistributions in binary form must reproduce the above copyright 36230557Sjimharris * notice, this list of conditions and the following disclaimer in 37230557Sjimharris * the documentation and/or other materials provided with the 38230557Sjimharris * distribution. 39230557Sjimharris * 40230557Sjimharris * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 41230557Sjimharris * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 42230557Sjimharris * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 43230557Sjimharris * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 44230557Sjimharris * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45230557Sjimharris * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 46230557Sjimharris * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 47230557Sjimharris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 48230557Sjimharris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49230557Sjimharris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 50230557Sjimharris * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51230557Sjimharris */ 52230557Sjimharris 53230557Sjimharris#include <sys/cdefs.h> 54230557Sjimharris__FBSDID("$FreeBSD$"); 55230557Sjimharris 56230557Sjimharris/** 57230557Sjimharris * @file 58230557Sjimharris * 59230557Sjimharris * @brief This file contains the method implementations for the 60230557Sjimharris * SCIF_SAS_SMP_IO_REQUEST object. The contents will implement SMP 61230557Sjimharris * specific functionality. 62230557Sjimharris */ 63230557Sjimharris 64230557Sjimharris#include <dev/isci/scil/scif_sas_smp_io_request.h> 65230557Sjimharris#include <dev/isci/scil/scif_sas_logger.h> 66230557Sjimharris#include <dev/isci/scil/scif_sas_controller.h> 67230557Sjimharris#include <dev/isci/scil/sci_controller.h> 68230557Sjimharris 69230557Sjimharris#include <dev/isci/scil/sci_status.h> 70230557Sjimharris#include <dev/isci/scil/scic_io_request.h> 71230557Sjimharris#include <dev/isci/scil/scic_user_callback.h> 72230557Sjimharris 73230557Sjimharris#include <dev/isci/scil/intel_sas.h> 74230557Sjimharris 75230557Sjimharris/** 76230557Sjimharris * @brief This routine is to fill in the space given by core the SMP command 77230557Sjimharris * frame. Then it calls core's construction. 78230557Sjimharris * 79230557Sjimharris * @param[in] fw_io The smp io request to be constructed. 80230557Sjimharris * @param[in] smp_command The SMP request filled according to SAS spec. 81230557Sjimharris * 82230557Sjimharris * @return none 83230557Sjimharris */ 84230557Sjimharrisvoid scif_sas_smp_request_construct( 85230557Sjimharris SCIF_SAS_REQUEST_T * fw_request, 86230557Sjimharris SMP_REQUEST_T * smp_command 87230557Sjimharris) 88230557Sjimharris{ 89230557Sjimharris void * command_iu_address = 90230557Sjimharris scic_io_request_get_command_iu_address(fw_request->core_object); 91230557Sjimharris 92230557Sjimharris //copy the smp_command to the address; 93230557Sjimharris memcpy( (char*) command_iu_address, 94230557Sjimharris smp_command, 95230557Sjimharris sizeof(SMP_REQUEST_T) 96230557Sjimharris ); 97230557Sjimharris 98230557Sjimharris scic_io_request_construct_smp(fw_request->core_object); 99230557Sjimharris 100230557Sjimharris fw_request->protocol_complete_handler 101230557Sjimharris = NULL; 102230557Sjimharris} 103230557Sjimharris 104230557Sjimharris/** 105230557Sjimharris * @brief This method will perform all of the construction common to all 106230557Sjimharris * SMP requests (e.g. filling in the frame type, zero-out memory, 107230557Sjimharris * etc.). 108230557Sjimharris * 109230557Sjimharris * @param[out] smp_request This parameter specifies the SMP request 110230557Sjimharris * structure containing the SMP request to be sent to the 111230557Sjimharris * SMP target. 112230557Sjimharris * @param[in] smp_function This parameter specifies the SMP function to 113230557Sjimharris * sent. 114230557Sjimharris * @param[in] smp_response_length This parameter specifies the length of 115230557Sjimharris * the response (in DWORDs) that will be returned for this 116230557Sjimharris * SMP request. 117230557Sjimharris * @param[in] smp_request_length This parameter specifies the length of 118230557Sjimharris * the request (in DWORDs) that will be sent. 119230557Sjimharris */ 120230557Sjimharrisstatic 121230557Sjimharrisvoid scif_sas_smp_protocol_request_construct( 122230557Sjimharris SMP_REQUEST_T * smp_request, 123230557Sjimharris U8 smp_function, 124230557Sjimharris U8 smp_response_length, 125230557Sjimharris U8 smp_request_length 126230557Sjimharris) 127230557Sjimharris{ 128230557Sjimharris memset((char*)smp_request, 0, sizeof(SMP_REQUEST_T)); 129230557Sjimharris 130230557Sjimharris smp_request->header.smp_frame_type = SMP_FRAME_TYPE_REQUEST; 131230557Sjimharris smp_request->header.function = smp_function; 132230557Sjimharris smp_request->header.allocated_response_length = smp_response_length; 133230557Sjimharris smp_request->header.request_length = smp_request_length; 134230557Sjimharris} 135230557Sjimharris 136230557Sjimharris 137230557Sjimharris/** 138230557Sjimharris * @brief This method will allocate the internal IO request object and 139230557Sjimharris * construct its contents based upon the supplied SMP request. 140230557Sjimharris * 141230557Sjimharris * @param[in] fw_controller This parameter specifies the controller object 142230557Sjimharris * from which to allocate the internal IO request. 143230557Sjimharris * @param[in] fw_device This parameter specifies the remote device for 144230557Sjimharris * which the internal IO request is destined. 145230557Sjimharris * @param[in] smp_request This parameter specifies the SMP request contents 146230557Sjimharris * to be sent to the SMP target. 147230557Sjimharris * 148230557Sjimharris * @return void * The address of built scif sas smp request. 149230557Sjimharris */ 150230557Sjimharrisstatic 151230557Sjimharrisvoid * scif_sas_smp_request_build( 152230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller, 153230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device, 154230557Sjimharris SMP_REQUEST_T * smp_request, 155230557Sjimharris void * external_request_object, 156230557Sjimharris void * external_memory 157230557Sjimharris) 158230557Sjimharris{ 159230557Sjimharris if (external_memory != NULL && external_request_object != NULL) 160230557Sjimharris { 161230557Sjimharris scif_sas_io_request_construct_smp( 162230557Sjimharris fw_controller, 163230557Sjimharris fw_device, 164230557Sjimharris external_memory, 165230557Sjimharris (char *)external_memory + sizeof(SCIF_SAS_IO_REQUEST_T), 166230557Sjimharris SCI_CONTROLLER_INVALID_IO_TAG, 167230557Sjimharris smp_request, 168230557Sjimharris external_request_object 169230557Sjimharris ); 170230557Sjimharris 171230557Sjimharris return external_memory; 172230557Sjimharris } 173230557Sjimharris else 174230557Sjimharris { 175230557Sjimharris void * internal_io_memory; 176230557Sjimharris internal_io_memory = scif_sas_controller_allocate_internal_request(fw_controller); 177230557Sjimharris ASSERT(internal_io_memory != NULL); 178230557Sjimharris 179230557Sjimharris if (internal_io_memory != NULL) 180230557Sjimharris { 181230557Sjimharris //construct, only when we got valid io memory. 182230557Sjimharris scif_sas_internal_io_request_construct_smp( 183230557Sjimharris fw_controller, 184230557Sjimharris fw_device, 185230557Sjimharris internal_io_memory, 186230557Sjimharris SCI_CONTROLLER_INVALID_IO_TAG, 187230557Sjimharris smp_request 188230557Sjimharris ); 189230557Sjimharris } 190230557Sjimharris else 191230557Sjimharris { 192230557Sjimharris SCIF_LOG_ERROR(( 193230557Sjimharris sci_base_object_get_logger(fw_controller), 194230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST, 195230557Sjimharris "scif_sas_smp_request_build, no memory available!\n" 196230557Sjimharris )); 197230557Sjimharris } 198230557Sjimharris 199230557Sjimharris return internal_io_memory; 200230557Sjimharris } 201230557Sjimharris} 202230557Sjimharris 203230557Sjimharris/** 204230557Sjimharris * @brief construct a smp Report Genernal command to the fw_device. 205230557Sjimharris * 206230557Sjimharris * @param[in] fw_controller The framework controller object. 207230557Sjimharris * @param[in] fw_device the framework device that the REPORT GENERAL command 208230557Sjimharris * targets to. 209230557Sjimharris * 210230557Sjimharris * @return void * address to the built scif sas smp request. 211230557Sjimharris */ 212230557Sjimharrisvoid * scif_sas_smp_request_construct_report_general( 213230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller, 214230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device 215230557Sjimharris) 216230557Sjimharris{ 217230557Sjimharris SMP_REQUEST_T smp_report_general; 218230557Sjimharris 219230557Sjimharris // Build the REPORT GENERAL request. 220230557Sjimharris scif_sas_smp_protocol_request_construct( 221230557Sjimharris &smp_report_general, 222230557Sjimharris SMP_FUNCTION_REPORT_GENERAL, 223230557Sjimharris sizeof(SMP_RESPONSE_REPORT_GENERAL_T) / sizeof(U32), 224230557Sjimharris 0 225230557Sjimharris ); 226230557Sjimharris 227230557Sjimharris smp_report_general.request.report_general.crc = 0; 228230557Sjimharris 229230557Sjimharris SCIF_LOG_INFO(( 230230557Sjimharris sci_base_object_get_logger(fw_device), 231230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY, 232230557Sjimharris "SMP REPORT GENERAL - Device:0x%x\n", 233230557Sjimharris fw_device 234230557Sjimharris )); 235230557Sjimharris 236230557Sjimharris return scif_sas_smp_request_build( 237230557Sjimharris fw_controller, fw_device, &smp_report_general, NULL, NULL); 238230557Sjimharris} 239230557Sjimharris 240230557Sjimharris/** 241230557Sjimharris * @brief construct a SMP Report Manufacturer Info request to the fw_device. 242230557Sjimharris * 243230557Sjimharris * @param[in] fw_controller The framework controller object. 244230557Sjimharris * @param[in] fw_device the framework device that the REPORT MANUFACTURER 245230557Sjimharris * INFO targets to. 246230557Sjimharris * 247230557Sjimharris * @return void * address to the built scif sas smp request. 248230557Sjimharris */ 249230557Sjimharrisvoid * scif_sas_smp_request_construct_report_manufacturer_info( 250230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller, 251230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device 252230557Sjimharris) 253230557Sjimharris{ 254230557Sjimharris SMP_REQUEST_T smp_report_manufacturer_info; 255230557Sjimharris 256230557Sjimharris scif_sas_smp_protocol_request_construct( 257230557Sjimharris &smp_report_manufacturer_info, 258230557Sjimharris SMP_FUNCTION_REPORT_MANUFACTURER_INFORMATION, 259230557Sjimharris sizeof(SMP_RESPONSE_REPORT_MANUFACTURER_INFORMATION_T) / sizeof(U32), 260230557Sjimharris 0 261230557Sjimharris ); 262230557Sjimharris 263230557Sjimharris smp_report_manufacturer_info.request.report_general.crc = 0; 264230557Sjimharris 265230557Sjimharris SCIF_LOG_INFO(( 266230557Sjimharris sci_base_object_get_logger(fw_device), 267230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY, 268230557Sjimharris "SMP REPORT MANUFACTURER_INFO - Device:0x%x\n", 269230557Sjimharris fw_device 270230557Sjimharris )); 271230557Sjimharris 272230557Sjimharris return scif_sas_smp_request_build( 273230557Sjimharris fw_controller, fw_device, &smp_report_manufacturer_info, NULL, NULL 274230557Sjimharris ); 275230557Sjimharris} 276230557Sjimharris 277230557Sjimharris/** 278230557Sjimharris * @brief construct a smp Discover command to the fw_device. 279230557Sjimharris * @param[in] fw_controller The framework controller object. 280230557Sjimharris * @param[in] fw_device the framework smp device that DISCOVER command targets 281230557Sjimharris * to. 282230557Sjimharris * @param[in] phy_identifier The phy index the DISCOVER command targets to. 283230557Sjimharris * 284230557Sjimharris * @return void * address to the built scif sas smp request. 285230557Sjimharris */ 286230557Sjimharrisvoid * scif_sas_smp_request_construct_discover( 287230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller, 288230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device, 289230557Sjimharris U8 phy_identifier, 290230557Sjimharris void * external_request_object, 291230557Sjimharris void * external_memory 292230557Sjimharris) 293230557Sjimharris{ 294230557Sjimharris SMP_REQUEST_T smp_discover; 295230557Sjimharris 296230557Sjimharris scif_sas_smp_protocol_request_construct( 297230557Sjimharris &smp_discover, 298230557Sjimharris SMP_FUNCTION_DISCOVER, 299230557Sjimharris sizeof(SMP_RESPONSE_DISCOVER_T) / sizeof(U32), 300230557Sjimharris sizeof(SMP_REQUEST_PHY_IDENTIFIER_T) / sizeof(U32) 301230557Sjimharris ); 302230557Sjimharris 303230557Sjimharris smp_discover.request.discover.phy_identifier = phy_identifier; 304230557Sjimharris 305230557Sjimharris SCIF_LOG_INFO(( 306230557Sjimharris sci_base_object_get_logger(fw_device), 307230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY, 308230557Sjimharris "SMP DISCOVER - Device:0x%x PhyId:0x%x\n", 309230557Sjimharris fw_device, phy_identifier 310230557Sjimharris )); 311230557Sjimharris 312230557Sjimharris return scif_sas_smp_request_build( 313230557Sjimharris fw_controller, fw_device, &smp_discover, 314230557Sjimharris external_request_object, external_memory 315230557Sjimharris ); 316230557Sjimharris} 317230557Sjimharris 318230557Sjimharris 319230557Sjimharris/** 320230557Sjimharris * @brief construct a smp REPORT PHY SATA command to the fw_device. 321230557Sjimharris * @param[in] fw_controller The framework controller object. 322230557Sjimharris * @param[in] fw_device the framework smp device that DISCOVER command targets 323230557Sjimharris * to. 324230557Sjimharris * @param[in] phy_identifier The phy index the DISCOVER command targets to. 325230557Sjimharris * 326230557Sjimharris * @return void * address to the built scif sas smp request. 327230557Sjimharris */ 328230557Sjimharrisvoid * scif_sas_smp_request_construct_report_phy_sata( 329230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller, 330230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device, 331230557Sjimharris U8 phy_identifier 332230557Sjimharris) 333230557Sjimharris{ 334230557Sjimharris SMP_REQUEST_T report_phy_sata; 335230557Sjimharris 336230557Sjimharris scif_sas_smp_protocol_request_construct( 337230557Sjimharris &report_phy_sata, 338230557Sjimharris SMP_FUNCTION_REPORT_PHY_SATA, 339230557Sjimharris sizeof(SMP_RESPONSE_REPORT_PHY_SATA_T) / sizeof(U32), 340230557Sjimharris sizeof(SMP_REQUEST_PHY_IDENTIFIER_T) / sizeof(U32) 341230557Sjimharris ); 342230557Sjimharris 343230557Sjimharris report_phy_sata.request.report_phy_sata.phy_identifier = phy_identifier; 344230557Sjimharris 345230557Sjimharris SCIF_LOG_INFO(( 346230557Sjimharris sci_base_object_get_logger(fw_device), 347230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY, 348230557Sjimharris "SMP REPORT PHY SATA - Device:0x%x PhyId:0x%x\n", 349230557Sjimharris fw_device, phy_identifier 350230557Sjimharris )); 351230557Sjimharris 352230557Sjimharris return scif_sas_smp_request_build( 353230557Sjimharris fw_controller, fw_device, &report_phy_sata, NULL, NULL); 354230557Sjimharris} 355230557Sjimharris 356230557Sjimharris 357230557Sjimharris/** 358230557Sjimharris * @brief construct a smp REPORT PHY SATA command to the fw_device. 359230557Sjimharris * @param[in] fw_controller The framework controller object. 360230557Sjimharris * @param[in] fw_device the framework smp device that PHY CONTROL command 361230557Sjimharris * targets to. 362230557Sjimharris * @param[in] phy_identifier The phy index the DISCOVER command targets to. 363230557Sjimharris * 364230557Sjimharris * @return void * address to the built scif sas smp request. 365230557Sjimharris */ 366230557Sjimharrisvoid * scif_sas_smp_request_construct_phy_control( 367230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller, 368230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device, 369230557Sjimharris U8 phy_operation, 370230557Sjimharris U8 phy_identifier, 371230557Sjimharris void * external_request_object, 372230557Sjimharris void * external_memory 373230557Sjimharris) 374230557Sjimharris{ 375230557Sjimharris SMP_REQUEST_T phy_control; 376230557Sjimharris 377230557Sjimharris scif_sas_smp_protocol_request_construct( 378230557Sjimharris &phy_control, 379230557Sjimharris SMP_FUNCTION_PHY_CONTROL, 380230557Sjimharris 0, 381230557Sjimharris sizeof(SMP_REQUEST_PHY_CONTROL_T) / sizeof(U32) 382230557Sjimharris ); 383230557Sjimharris 384230557Sjimharris phy_control.request.phy_control.phy_operation = phy_operation; 385230557Sjimharris phy_control.request.phy_control.phy_identifier = phy_identifier; 386230557Sjimharris 387230557Sjimharris return scif_sas_smp_request_build( 388230557Sjimharris fw_controller, fw_device, &phy_control, 389230557Sjimharris external_request_object, external_memory 390230557Sjimharris ); 391230557Sjimharris} 392230557Sjimharris 393230557Sjimharris 394230557Sjimharris/** 395230557Sjimharris * @brief construct a smp CONFIG ROUTE INFO command to the fw_device. 396230557Sjimharris * 397230557Sjimharris * @param[in] fw_controller The framework controller object. 398230557Sjimharris * @param[in] fw_device the framework smp device that PHY CONTROL command 399230557Sjimharris * targets to. 400230557Sjimharris * @param[in] phy_id The phy, whose route entry at route_index is to be configured. 401230557Sjimharris * @param[in] route_index The index of a phy's route entry that is to be configured. 402230557Sjimharris * @param[in] destination_sas_address A sas address for an route table entry 403230557Sjimharris * 404230557Sjimharris * @return void * address to the built scif sas smp request. 405230557Sjimharris */ 406230557Sjimharrisvoid * scif_sas_smp_request_construct_config_route_info( 407230557Sjimharris struct SCIF_SAS_CONTROLLER * fw_controller, 408230557Sjimharris struct SCIF_SAS_REMOTE_DEVICE * fw_device, 409230557Sjimharris U8 phy_id, 410230557Sjimharris U16 route_index, 411230557Sjimharris SCI_SAS_ADDRESS_T destination_sas_address, 412230557Sjimharris BOOL disable_expander_route_entry 413230557Sjimharris) 414230557Sjimharris{ 415230557Sjimharris SMP_REQUEST_T config_route_info; 416230557Sjimharris 417230557Sjimharris scif_sas_smp_protocol_request_construct( 418230557Sjimharris &config_route_info, 419230557Sjimharris SMP_FUNCTION_CONFIGURE_ROUTE_INFORMATION, 420230557Sjimharris 0, 421230557Sjimharris sizeof(SMP_REQUEST_CONFIGURE_ROUTE_INFORMATION_T) / sizeof(U32) 422230557Sjimharris ); 423230557Sjimharris 424230557Sjimharris config_route_info.request.configure_route_information.phy_identifier = phy_id; 425230557Sjimharris config_route_info.request.configure_route_information.expander_route_index_high = 426230557Sjimharris ((route_index & 0xff00) >> 8); 427230557Sjimharris config_route_info.request.configure_route_information.expander_route_index = 428230557Sjimharris route_index & 0xff; 429230557Sjimharris config_route_info.request.configure_route_information.routed_sas_address[0] = 430230557Sjimharris destination_sas_address.high; 431230557Sjimharris config_route_info.request.configure_route_information.routed_sas_address[1] = 432230557Sjimharris destination_sas_address.low; 433230557Sjimharris 434230557Sjimharris if (disable_expander_route_entry == TRUE) 435230557Sjimharris config_route_info.request.configure_route_information.disable_route_entry = 1; 436230557Sjimharris 437230557Sjimharris return scif_sas_smp_request_build( 438230557Sjimharris fw_controller, fw_device, &config_route_info, 439230557Sjimharris NULL, NULL 440230557Sjimharris ); 441230557Sjimharris} 442230557Sjimharris 443230557Sjimharris/** 444230557Sjimharris * @brief This method retry the internal smp request. 445230557Sjimharris * 446230557Sjimharris * @param[in] fw_device This parameter specifies the remote device for 447230557Sjimharris * which the internal IO request is destined. 448230557Sjimharris * @param[in] retry_count This parameter specifies how many times the 449230557Sjimharris * old smp request has been retried. 450230557Sjimharris * 451230557Sjimharris * @return none. 452230557Sjimharris */ 453230557SjimharrisSCI_STATUS scif_sas_smp_internal_request_retry( 454230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device 455230557Sjimharris) 456230557Sjimharris{ 457230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller; 458230557Sjimharris SCIF_SAS_IO_REQUEST_T * new_io; 459230557Sjimharris void * new_request_memory = NULL; 460230557Sjimharris U8 retry_count = fw_device->protocol_device.smp_device.io_retry_count; 461230557Sjimharris 462230557Sjimharris SCIF_LOG_TRACE(( 463230557Sjimharris sci_base_object_get_logger(fw_device), 464230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY, 465230557Sjimharris "scif_sas_smp_internal_request_retry(0x%x, 0x%x) time %d!\n", 466230557Sjimharris fw_device, retry_count 467230557Sjimharris )); 468230557Sjimharris 469230557Sjimharris fw_controller = fw_device->domain->controller; 470230557Sjimharris 471230557Sjimharris switch (fw_device->protocol_device.smp_device.current_smp_request) 472230557Sjimharris { 473230557Sjimharris case SMP_FUNCTION_REPORT_GENERAL: 474230557Sjimharris new_request_memory = scif_sas_smp_request_construct_report_general( 475230557Sjimharris fw_controller, fw_device 476230557Sjimharris ); 477230557Sjimharris break; 478230557Sjimharris 479230557Sjimharris case SMP_FUNCTION_DISCOVER: 480230557Sjimharris //We are retrying an internal io. So we are going to allocate 481230557Sjimharris //a new memory from internal io memory pool. 482230557Sjimharris new_request_memory = scif_sas_smp_request_construct_discover( 483230557Sjimharris fw_controller, fw_device, 484230557Sjimharris fw_device->protocol_device.smp_device.current_activity_phy_index, 485230557Sjimharris NULL, NULL 486230557Sjimharris ); 487230557Sjimharris 488230557Sjimharris break; 489230557Sjimharris 490230557Sjimharris case SMP_FUNCTION_REPORT_PHY_SATA: 491230557Sjimharris new_request_memory = scif_sas_smp_request_construct_report_phy_sata( 492230557Sjimharris fw_controller, fw_device, 493230557Sjimharris fw_device->protocol_device.smp_device.current_activity_phy_index 494230557Sjimharris ); 495230557Sjimharris break; 496230557Sjimharris 497230557Sjimharris default: 498230557Sjimharris //unsupported case, TBD 499230557Sjimharris break; 500230557Sjimharris } //end of switch 501230557Sjimharris 502230557Sjimharris if (new_request_memory != NULL) 503230557Sjimharris { 504230557Sjimharris //set the retry count to new built smp request. 505230557Sjimharris new_io = (SCIF_SAS_IO_REQUEST_T *) new_request_memory; 506230557Sjimharris new_io->retry_count = ++retry_count; 507230557Sjimharris 508230557Sjimharris //need to schedule the DPC here. 509230557Sjimharris scif_cb_start_internal_io_task_schedule( 510230557Sjimharris fw_controller, 511230557Sjimharris scif_sas_controller_start_high_priority_io, 512230557Sjimharris fw_controller 513230557Sjimharris ); 514230557Sjimharris 515230557Sjimharris return SCI_SUCCESS; 516230557Sjimharris } 517230557Sjimharris else 518230557Sjimharris return SCI_FAILURE_INSUFFICIENT_RESOURCES; 519230557Sjimharris 520230557Sjimharris} 521230557Sjimharris 522230557Sjimharris/** 523230557Sjimharris * @brief This method retry the external smp request. 524230557Sjimharris * 525230557Sjimharris * @param[in] fw_device This parameter specifies the remote device for 526230557Sjimharris * which the internal IO request is destined. 527230557Sjimharris * @param[in] old_internal_io This parameter specifies the old smp request to be 528230557Sjimharris * retried. 529230557Sjimharris * 530230557Sjimharris * @return none. 531230557Sjimharris */ 532230557SjimharrisSCI_STATUS scif_sas_smp_external_request_retry( 533230557Sjimharris SCIF_SAS_IO_REQUEST_T * old_io 534230557Sjimharris) 535230557Sjimharris{ 536230557Sjimharris SCIF_SAS_REMOTE_DEVICE_T * fw_device = old_io->parent.device; 537230557Sjimharris SCIF_SAS_CONTROLLER_T * fw_controller; 538230557Sjimharris SCIF_SAS_IO_REQUEST_T * new_io; 539230557Sjimharris void * new_request_memory = NULL; 540230557Sjimharris U8 retry_count = old_io->retry_count; 541230557Sjimharris 542230557Sjimharris SCIF_LOG_TRACE(( 543230557Sjimharris sci_base_object_get_logger(fw_device), 544230557Sjimharris SCIF_LOG_OBJECT_IO_REQUEST | SCIF_LOG_OBJECT_DOMAIN_DISCOVERY, 545230557Sjimharris "scif_sas_smp_external_request_retry(0x%x) time %d!\n", 546230557Sjimharris old_io 547230557Sjimharris )); 548230557Sjimharris 549230557Sjimharris fw_controller = fw_device->domain->controller; 550230557Sjimharris 551230557Sjimharris // Before we construct new io using the same memory, we need to 552230557Sjimharris // remove the IO from the list of outstanding requests on the domain 553230557Sjimharris // so that we don't damage the domain's fast list of request. 554230557Sjimharris sci_fast_list_remove_element(&old_io->parent.list_element); 555230557Sjimharris 556230557Sjimharris switch (fw_device->protocol_device.smp_device.current_smp_request) 557230557Sjimharris { 558230557Sjimharris case SMP_FUNCTION_DISCOVER: 559230557Sjimharris //we are retrying an external io, we are going to reuse the 560230557Sjimharris //old io's memory. new_request_memory is same as old_io. 561230557Sjimharris new_request_memory = scif_sas_smp_request_construct_discover( 562230557Sjimharris fw_controller, fw_device, 563230557Sjimharris fw_device->protocol_device.smp_device.current_activity_phy_index, 564230557Sjimharris (void *)sci_object_get_association(old_io), 565230557Sjimharris (void *)old_io 566230557Sjimharris ); 567230557Sjimharris 568230557Sjimharris break; 569230557Sjimharris 570230557Sjimharris case SMP_FUNCTION_PHY_CONTROL: 571230557Sjimharris //Phy Control command always uses external io memory. 572230557Sjimharris new_request_memory = scif_sas_smp_request_construct_phy_control( 573230557Sjimharris fw_controller, fw_device, PHY_OPERATION_HARD_RESET, 574230557Sjimharris fw_device->protocol_device.smp_device.current_activity_phy_index, 575230557Sjimharris (void *)sci_object_get_association(old_io), 576230557Sjimharris (void *)old_io 577230557Sjimharris ); 578230557Sjimharris 579230557Sjimharris break; 580230557Sjimharris 581230557Sjimharris default: 582230557Sjimharris //unsupported case, TBD 583231137Sjimharris return SCI_FAILURE; 584230557Sjimharris } //end of switch 585230557Sjimharris 586230557Sjimharris //set the retry count to new built smp request. 587230557Sjimharris new_io = (SCIF_SAS_IO_REQUEST_T *) new_request_memory; 588230557Sjimharris new_io->retry_count = ++retry_count; 589230557Sjimharris 590230557Sjimharris //put into the high priority queue. 591230557Sjimharris sci_pool_put(fw_controller->hprq.pool, (POINTER_UINT) new_request_memory); 592230557Sjimharris 593230557Sjimharris //schedule the DPC to start new io. 594230557Sjimharris scif_cb_start_internal_io_task_schedule( 595230557Sjimharris fw_controller, scif_sas_controller_start_high_priority_io, fw_controller 596230557Sjimharris ); 597230557Sjimharris 598230557Sjimharris return SCI_SUCCESS; 599230557Sjimharris} 600230557Sjimharris 601