1 /*- 2 * This file is provided under a dual BSD/GPLv2 license. When using or 3 * redistributing this file, you may do so under either license. 4 * 5 * GPL LICENSE SUMMARY 6 * 7 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of version 2 of the GNU General Public License as 11 * published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 21 * The full GNU General Public License is included in this distribution 22 * in the file called LICENSE.GPL. 23 * 24 * BSD LICENSE 25 * 26 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 27 * All rights reserved. 28 * 29 * Redistribution and use in source and binary forms, with or without 30 * modification, are permitted provided that the following conditions 31 * are met: 32 * 33 * * Redistributions of source code must retain the above copyright 34 * notice, this list of conditions and the following disclaimer. 35 * * Redistributions in binary form must reproduce the above copyright 36 * notice, this list of conditions and the following disclaimer in 37 * the documentation and/or other materials provided with the 38 * distribution. 39 * 40 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 41 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 42 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 43 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 44 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 46 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 47 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 48 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 49 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 50 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 51 */ 52 53 #include <sys/cdefs.h> 54 __FBSDID("$FreeBSD$"); 55 56 /** 57 * @file 58 * 59 * @brief This file contains all of the method implementations pertaining 60 * to the framework io request state handler methods. 61 */ 62 63 #include <dev/isci/scil/scif_sas_logger.h> 64 #include <dev/isci/scil/scif_sas_task_request.h> 65 66 //****************************************************************************** 67 //* C O N S T R U C T E D H A N D L E R S 68 //****************************************************************************** 69 70 /** 71 * @brief This method provides CONSTRUCTED state specific handling for 72 * when the user attempts to start the supplied task request. 73 * 74 * @param[in] task_request This parameter specifies the task request object 75 * to be started. 76 * 77 * @return This method returns a value indicating if the task request was 78 * successfully started or not. 79 * @retval SCI_SUCCESS This return value indicates successful starting 80 * of the task request. 81 */ 82 static 83 SCI_STATUS scif_sas_task_request_constructed_start_handler( 84 SCI_BASE_REQUEST_T * task_request 85 ) 86 { 87 sci_base_state_machine_change_state( 88 &task_request->state_machine, SCI_BASE_REQUEST_STATE_STARTED 89 ); 90 91 return SCI_SUCCESS; 92 } 93 94 /** 95 * @brief This method provides CONSTRUCTED state specific handling for 96 * when the user attempts to abort the supplied task request. 97 * 98 * @param[in] task_request This parameter specifies the task request object 99 * to be aborted. 100 * 101 * @return This method returns a value indicating if the task request was 102 * successfully aborted or not. 103 * @retval SCI_SUCCESS This return value indicates successful aborting 104 * of the task request. 105 */ 106 static 107 SCI_STATUS scif_sas_task_request_constructed_abort_handler( 108 SCI_BASE_REQUEST_T * task_request 109 ) 110 { 111 sci_base_state_machine_change_state( 112 &task_request->state_machine, SCI_BASE_REQUEST_STATE_COMPLETED 113 ); 114 115 return SCI_SUCCESS; 116 } 117 118 //****************************************************************************** 119 //* S T A R T E D H A N D L E R S 120 //****************************************************************************** 121 122 /** 123 * @brief This method provides STARTED state specific handling for 124 * when the user attempts to abort the supplied task request. 125 * 126 * @param[in] task_request This parameter specifies the task request object 127 * to be aborted. 128 * 129 * @return This method returns a value indicating if the aborting the 130 * task request was successfully started. 131 * @retval SCI_SUCCESS This return value indicates that the abort process 132 * began successfully. 133 */ 134 static 135 SCI_STATUS scif_sas_task_request_started_abort_handler( 136 SCI_BASE_REQUEST_T * task_request 137 ) 138 { 139 SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T *) task_request; 140 141 sci_base_state_machine_change_state( 142 &task_request->state_machine, SCI_BASE_REQUEST_STATE_ABORTING 143 ); 144 145 return fw_request->status; 146 } 147 148 /** 149 * @brief This method provides STARTED state specific handling for 150 * when the user attempts to complete the supplied task request. 151 * 152 * @param[in] task_request This parameter specifies the task request object 153 * to be completed. 154 * 155 * @return This method returns a value indicating if the completion of the 156 * task request was successful. 157 * @retval SCI_SUCCESS This return value indicates that the completion process 158 * was successful. 159 */ 160 static 161 SCI_STATUS scif_sas_task_request_started_complete_handler( 162 SCI_BASE_REQUEST_T * task_request 163 ) 164 { 165 sci_base_state_machine_change_state( 166 &task_request->state_machine, SCI_BASE_REQUEST_STATE_COMPLETED 167 ); 168 169 return SCI_SUCCESS; 170 } 171 172 //****************************************************************************** 173 //* C O M P L E T E D H A N D L E R S 174 //****************************************************************************** 175 176 /** 177 * @brief This method provides COMPLETED state specific handling for 178 * when the user attempts to destruct the supplied task request. 179 * 180 * @param[in] task_request This parameter specifies the task request object 181 * to be destructed. 182 * 183 * @return This method returns a value indicating if the destruct 184 * operation was successful. 185 * @retval SCI_SUCCESS This return value indicates that the destruct 186 * was successful. 187 */ 188 static 189 SCI_STATUS scif_sas_task_request_completed_destruct_handler( 190 SCI_BASE_REQUEST_T * task_request 191 ) 192 { 193 SCIF_SAS_REQUEST_T * fw_request = (SCIF_SAS_REQUEST_T *)task_request; 194 195 sci_base_state_machine_change_state( 196 &task_request->state_machine, SCI_BASE_REQUEST_STATE_FINAL 197 ); 198 199 sci_base_state_machine_logger_deinitialize( 200 &task_request->state_machine_logger, 201 &task_request->state_machine 202 ); 203 204 if (fw_request->is_internal == TRUE) 205 { 206 scif_sas_internal_task_request_destruct( 207 (SCIF_SAS_TASK_REQUEST_T *)fw_request 208 ); 209 } 210 211 return SCI_SUCCESS; 212 } 213 214 //****************************************************************************** 215 //* A B O R T I N G H A N D L E R S 216 //****************************************************************************** 217 218 /** 219 * @brief This method provides ABORTING state specific handling for 220 * when the user attempts to complete the supplied task request. 221 * 222 * @param[in] task_request This parameter specifies the task request object 223 * to be completed. 224 * 225 * @return This method returns a value indicating if the completion 226 * operation was successful. 227 * @retval SCI_SUCCESS This return value indicates that the completion 228 * was successful. 229 */ 230 static 231 SCI_STATUS scif_sas_task_request_aborting_complete_handler( 232 SCI_BASE_REQUEST_T * task_request 233 ) 234 { 235 sci_base_state_machine_change_state( 236 &task_request->state_machine, SCI_BASE_REQUEST_STATE_COMPLETED 237 ); 238 239 return SCI_SUCCESS; 240 } 241 242 //****************************************************************************** 243 //* D E F A U L T H A N D L E R S 244 //****************************************************************************** 245 246 /** 247 * @brief This method provides DEFAULT handling for when the user 248 * attempts to start the supplied task request. 249 * 250 * @param[in] task_request This parameter specifies the task request object 251 * to be started. 252 * 253 * @return This method returns an indication that the start operation is 254 * not allowed. 255 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 256 */ 257 static 258 SCI_STATUS scif_sas_task_request_default_start_handler( 259 SCI_BASE_REQUEST_T * task_request 260 ) 261 { 262 SCIF_LOG_ERROR(( 263 sci_base_object_get_logger((SCIF_SAS_TASK_REQUEST_T *) task_request), 264 SCIF_LOG_OBJECT_TASK_MANAGEMENT, 265 "TaskRequest:0x%x State:0x%x invalid state to start\n", 266 task_request, 267 sci_base_state_machine_get_state( 268 &((SCIF_SAS_TASK_REQUEST_T *) task_request)->parent.parent.state_machine) 269 )); 270 271 return SCI_FAILURE_INVALID_STATE; 272 } 273 274 /** 275 * @brief This method provides DEFAULT handling for when the user 276 * attempts to abort the supplied task request. 277 * 278 * @param[in] task_request This parameter specifies the task request object 279 * to be aborted. 280 * 281 * @return This method returns an indication that the abort operation is 282 * not allowed. 283 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 284 */ 285 static 286 SCI_STATUS scif_sas_task_request_default_abort_handler( 287 SCI_BASE_REQUEST_T * task_request 288 ) 289 { 290 SCIF_LOG_ERROR(( 291 sci_base_object_get_logger((SCIF_SAS_TASK_REQUEST_T *) task_request), 292 SCIF_LOG_OBJECT_TASK_MANAGEMENT, 293 "TaskRequest:0x%x State:0x%x invalid state to abort\n", 294 task_request, 295 sci_base_state_machine_get_state( 296 &((SCIF_SAS_TASK_REQUEST_T *) task_request)->parent.parent.state_machine) 297 )); 298 299 return SCI_FAILURE_INVALID_STATE; 300 } 301 302 /** 303 * @brief This method provides DEFAULT handling for when the user 304 * attempts to complete the supplied task request. 305 * 306 * @param[in] task_request This parameter specifies the task request object 307 * to be completed. 308 * 309 * @return This method returns an indication that complete operation is 310 * not allowed. 311 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 312 */ 313 static 314 SCI_STATUS scif_sas_task_request_default_complete_handler( 315 SCI_BASE_REQUEST_T * task_request 316 ) 317 { 318 SCIF_LOG_ERROR(( 319 sci_base_object_get_logger((SCIF_SAS_TASK_REQUEST_T *) task_request), 320 SCIF_LOG_OBJECT_TASK_MANAGEMENT, 321 "TaskRequest:0x%x State:0x%x invalid state to complete\n", 322 task_request, 323 sci_base_state_machine_get_state( 324 &((SCIF_SAS_TASK_REQUEST_T *) task_request)->parent.parent.state_machine) 325 )); 326 327 return SCI_FAILURE_INVALID_STATE; 328 } 329 330 /** 331 * @brief This method provides DEFAULT handling for when the user 332 * attempts to destruct the supplied task request. 333 * 334 * @param[in] task_request This parameter specifies the task request object 335 * to be destructed. 336 * 337 * @return This method returns an indication that destruct operation is 338 * not allowed. 339 * @retval SCI_FAILURE_INVALID_STATE This value is always returned. 340 */ 341 static 342 SCI_STATUS scif_sas_task_request_default_destruct_handler( 343 SCI_BASE_REQUEST_T * task_request 344 ) 345 { 346 SCIF_LOG_ERROR(( 347 sci_base_object_get_logger((SCIF_SAS_TASK_REQUEST_T *) task_request), 348 SCIF_LOG_OBJECT_TASK_MANAGEMENT, 349 "TaskRequest:0x%x State:0x%x invalid state to destruct.\n", 350 task_request, 351 sci_base_state_machine_get_state( 352 &((SCIF_SAS_TASK_REQUEST_T *) task_request)->parent.parent.state_machine) 353 )); 354 355 return SCI_FAILURE_INVALID_STATE; 356 } 357 358 359 SCI_BASE_REQUEST_STATE_HANDLER_T scif_sas_task_request_state_handler_table[] = 360 { 361 // SCI_BASE_REQUEST_STATE_INITIAL 362 { 363 scif_sas_task_request_default_start_handler, 364 scif_sas_task_request_default_abort_handler, 365 scif_sas_task_request_default_complete_handler, 366 scif_sas_task_request_default_destruct_handler 367 }, 368 // SCI_BASE_REQUEST_STATE_CONSTRUCTED 369 { 370 scif_sas_task_request_constructed_start_handler, 371 scif_sas_task_request_constructed_abort_handler, 372 scif_sas_task_request_default_complete_handler, 373 scif_sas_task_request_default_destruct_handler 374 }, 375 // SCI_BASE_REQUEST_STATE_STARTED 376 { 377 scif_sas_task_request_default_start_handler, 378 scif_sas_task_request_started_abort_handler, 379 scif_sas_task_request_started_complete_handler, 380 scif_sas_task_request_default_destruct_handler 381 }, 382 // SCI_BASE_REQUEST_STATE_COMPLETED 383 { 384 scif_sas_task_request_default_start_handler, 385 scif_sas_task_request_default_abort_handler, 386 scif_sas_task_request_default_complete_handler, 387 scif_sas_task_request_completed_destruct_handler 388 }, 389 // SCI_BASE_REQUEST_STATE_ABORTING 390 { 391 scif_sas_task_request_default_start_handler, 392 scif_sas_task_request_default_abort_handler, 393 scif_sas_task_request_aborting_complete_handler, 394 scif_sas_task_request_default_destruct_handler 395 }, 396 // SCI_BASE_REQUEST_STATE_FINAL 397 { 398 scif_sas_task_request_default_start_handler, 399 scif_sas_task_request_default_abort_handler, 400 scif_sas_task_request_default_complete_handler, 401 scif_sas_task_request_default_destruct_handler 402 }, 403 }; 404 405