1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause OR GPL-2.0 3 * 4 * This file is provided under a dual BSD/GPLv2 license. When using or 5 * redistributing this file, you may do so under either license. 6 * 7 * GPL LICENSE SUMMARY 8 * 9 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of version 2 of the GNU General Public License as 13 * published by the Free Software Foundation. 14 * 15 * This program is distributed in the hope that it will be useful, but 16 * WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 18 * General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 23 * The full GNU General Public License is included in this distribution 24 * in the file called LICENSE.GPL. 25 * 26 * BSD LICENSE 27 * 28 * Copyright(c) 2008 - 2011 Intel Corporation. All rights reserved. 29 * All rights reserved. 30 * 31 * Redistribution and use in source and binary forms, with or without 32 * modification, are permitted provided that the following conditions 33 * are met: 34 * 35 * * Redistributions of source code must retain the above copyright 36 * notice, this list of conditions and the following disclaimer. 37 * * Redistributions in binary form must reproduce the above copyright 38 * notice, this list of conditions and the following disclaimer in 39 * the documentation and/or other materials provided with the 40 * distribution. 41 * 42 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 43 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 44 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 45 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 46 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 47 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 48 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 49 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 50 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 51 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 52 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 53 */ 54 55 #include <sys/cdefs.h> 56 __FBSDID("$FreeBSD$"); 57 58 /** 59 * @file 60 * 61 * @brief This file contains the implementation of remote device, it's 62 * methods and state machine. 63 */ 64 65 #include <dev/isci/scil/intel_sas.h> 66 #include <dev/isci/scil/sci_util.h> 67 #include <dev/isci/scil/scic_port.h> 68 #include <dev/isci/scil/scic_phy.h> 69 #include <dev/isci/scil/scic_remote_device.h> 70 #include <dev/isci/scil/scic_sds_port.h> 71 #include <dev/isci/scil/scic_sds_phy.h> 72 #include <dev/isci/scil/scic_sds_remote_device.h> 73 #include <dev/isci/scil/scic_sds_request.h> 74 #include <dev/isci/scil/scic_sds_controller.h> 75 #include <dev/isci/scil/scic_sds_logger.h> 76 #include <dev/isci/scil/scic_user_callback.h> 77 #include <dev/isci/scil/scic_controller.h> 78 #include <dev/isci/scil/scic_sds_logger.h> 79 #include <dev/isci/scil/scic_sds_remote_node_context.h> 80 #include <dev/isci/scil/scu_event_codes.h> 81 82 #define SCIC_SDS_REMOTE_DEVICE_RESET_TIMEOUT (1000) 83 84 //***************************************************************************** 85 //* CORE REMOTE DEVICE PUBLIC METHODS 86 //***************************************************************************** 87 88 U32 scic_remote_device_get_object_size(void) 89 { 90 return sizeof(SCIC_SDS_REMOTE_DEVICE_T) 91 + sizeof(SCIC_SDS_REMOTE_NODE_CONTEXT_T); 92 } 93 94 // --------------------------------------------------------------------------- 95 96 void scic_remote_device_construct( 97 SCI_PORT_HANDLE_T port, 98 void * remote_device_memory, 99 SCI_REMOTE_DEVICE_HANDLE_T * new_remote_device_handle 100 ) 101 { 102 SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T*) 103 remote_device_memory; 104 SCIC_SDS_PORT_T *the_port = (SCIC_SDS_PORT_T*) port; 105 106 SCIC_LOG_TRACE(( 107 sci_base_object_get_logger(the_port), 108 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 109 SCIC_LOG_OBJECT_STP_REMOTE_TARGET | 110 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET, 111 "scic_remote_device_construct(0x%x, 0x%x, 0x%x) enter\n", 112 port, remote_device_memory, new_remote_device_handle 113 )); 114 115 memset(remote_device_memory, 0, sizeof(SCIC_SDS_REMOTE_DEVICE_T)); 116 117 *new_remote_device_handle = this_device; 118 this_device->owning_port = the_port; 119 this_device->started_request_count = 0; 120 this_device->rnc = (SCIC_SDS_REMOTE_NODE_CONTEXT_T *) 121 ((char *)this_device + sizeof(SCIC_SDS_REMOTE_DEVICE_T)); 122 123 sci_base_remote_device_construct( 124 &this_device->parent, 125 sci_base_object_get_logger(the_port), 126 scic_sds_remote_device_state_table 127 ); 128 129 scic_sds_remote_node_context_construct( 130 this_device, 131 this_device->rnc, 132 SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX 133 ); 134 135 sci_object_set_association(this_device->rnc, this_device); 136 137 scic_sds_remote_device_initialize_state_logging(this_device); 138 } 139 140 // --------------------------------------------------------------------------- 141 142 SCI_STATUS scic_remote_device_da_construct( 143 SCI_REMOTE_DEVICE_HANDLE_T remote_device 144 ) 145 { 146 SCI_STATUS status; 147 U16 remote_node_index; 148 SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T*) 149 remote_device; 150 SCI_SAS_IDENTIFY_ADDRESS_FRAME_PROTOCOLS_T protocols; 151 SCIC_PORT_PROPERTIES_T properties; 152 153 SCIC_LOG_TRACE(( 154 sci_base_object_get_logger(this_device->owning_port), 155 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 156 SCIC_LOG_OBJECT_STP_REMOTE_TARGET | 157 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET, 158 "scic_remote_device_da_construct(0x%x) enter\n", 159 remote_device 160 )); 161 162 // This information is request to determine how many remote node context 163 // entries will be needed to store the remote node. 164 scic_sds_port_get_attached_protocols(this_device->owning_port,&protocols); 165 this_device->target_protocols.u.all = protocols.u.all; 166 this_device->is_direct_attached = TRUE; 167 #if !defined(DISABLE_ATAPI) 168 this_device->is_atapi = scic_sds_remote_device_is_atapi(this_device); 169 #endif 170 171 scic_port_get_properties(this_device->owning_port, &properties); 172 //Get accurate port width from port's phy mask for a DA device. 173 SCI_GET_BITS_SET_COUNT(properties.phy_mask, this_device->device_port_width); 174 175 status = scic_sds_controller_allocate_remote_node_context( 176 this_device->owning_port->owning_controller, 177 this_device, 178 &remote_node_index 179 ); 180 181 if (status == SCI_SUCCESS) 182 { 183 scic_sds_remote_node_context_set_remote_node_index( 184 this_device->rnc, remote_node_index 185 ); 186 187 scic_sds_port_get_attached_sas_address( 188 this_device->owning_port, &this_device->device_address 189 ); 190 191 if (this_device->target_protocols.u.bits.attached_ssp_target) 192 { 193 this_device->has_ready_substate_machine = FALSE; 194 } 195 else if (this_device->target_protocols.u.bits.attached_stp_target) 196 { 197 this_device->has_ready_substate_machine = TRUE; 198 199 sci_base_state_machine_construct( 200 &this_device->ready_substate_machine, 201 &this_device->parent.parent, 202 scic_sds_stp_remote_device_ready_substate_table, 203 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE 204 ); 205 } 206 else if (this_device->target_protocols.u.bits.attached_smp_target) 207 { 208 this_device->has_ready_substate_machine = TRUE; 209 210 //add the SMP ready substate machine construction here 211 sci_base_state_machine_construct( 212 &this_device->ready_substate_machine, 213 &this_device->parent.parent, 214 scic_sds_smp_remote_device_ready_substate_table, 215 SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE 216 ); 217 } 218 219 this_device->connection_rate = scic_sds_port_get_max_allowed_speed( 220 this_device->owning_port 221 ); 222 223 /// @todo Should I assign the port width by reading all of the phys on the port? 224 this_device->device_port_width = 1; 225 } 226 227 return status; 228 } 229 230 231 // --------------------------------------------------------------------------- 232 233 void scic_sds_remote_device_get_info_from_smp_discover_response( 234 SCIC_SDS_REMOTE_DEVICE_T * this_device, 235 SMP_RESPONSE_DISCOVER_T * discover_response 236 ) 237 { 238 // decode discover_response to set sas_address to this_device. 239 this_device->device_address.high = 240 discover_response->attached_sas_address.high; 241 242 this_device->device_address.low = 243 discover_response->attached_sas_address.low; 244 245 this_device->target_protocols.u.all = discover_response->protocols.u.all; 246 } 247 248 249 // --------------------------------------------------------------------------- 250 251 SCI_STATUS scic_remote_device_ea_construct( 252 SCI_REMOTE_DEVICE_HANDLE_T remote_device, 253 SMP_RESPONSE_DISCOVER_T * discover_response 254 ) 255 { 256 SCI_STATUS status; 257 258 SCIC_SDS_REMOTE_DEVICE_T *this_device; 259 SCIC_SDS_CONTROLLER_T *the_controller; 260 261 this_device = (SCIC_SDS_REMOTE_DEVICE_T *)remote_device; 262 263 SCIC_LOG_TRACE(( 264 sci_base_object_get_logger(this_device->owning_port), 265 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 266 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET, 267 "scic_remote_device_ea_sas_construct0x%x, 0x%x) enter\n", 268 remote_device, discover_response 269 )); 270 271 the_controller = scic_sds_port_get_controller(this_device->owning_port); 272 273 scic_sds_remote_device_get_info_from_smp_discover_response( 274 this_device, discover_response 275 ); 276 277 status = scic_sds_controller_allocate_remote_node_context( 278 the_controller, 279 this_device, 280 &this_device->rnc->remote_node_index 281 ); 282 283 if (status == SCI_SUCCESS) 284 { 285 if (this_device->target_protocols.u.bits.attached_ssp_target) 286 { 287 this_device->has_ready_substate_machine = FALSE; 288 } 289 else if (this_device->target_protocols.u.bits.attached_smp_target) 290 { 291 this_device->has_ready_substate_machine = TRUE; 292 293 //add the SMP ready substate machine construction here 294 sci_base_state_machine_construct( 295 &this_device->ready_substate_machine, 296 &this_device->parent.parent, 297 scic_sds_smp_remote_device_ready_substate_table, 298 SCIC_SDS_SMP_REMOTE_DEVICE_READY_SUBSTATE_IDLE 299 ); 300 } 301 else if (this_device->target_protocols.u.bits.attached_stp_target) 302 { 303 this_device->has_ready_substate_machine = TRUE; 304 305 sci_base_state_machine_construct( 306 &this_device->ready_substate_machine, 307 &this_device->parent.parent, 308 scic_sds_stp_remote_device_ready_substate_table, 309 SCIC_SDS_STP_REMOTE_DEVICE_READY_SUBSTATE_IDLE 310 ); 311 } 312 313 // For SAS-2 the physical link rate is actually a logical link 314 // rate that incorporates multiplexing. The SCU doesn't 315 // incorporate multiplexing and for the purposes of the 316 // connection the logical link rate is that same as the 317 // physical. Furthermore, the SAS-2 and SAS-1.1 fields overlay 318 // one another, so this code works for both situations. 319 this_device->connection_rate = MIN( 320 scic_sds_port_get_max_allowed_speed( this_device->owning_port), 321 discover_response->u2.sas1_1.negotiated_physical_link_rate 322 ); 323 324 /// @todo Should I assign the port width by reading all of the phys on the port? 325 this_device->device_port_width = 1; 326 } 327 328 return status; 329 } 330 331 // --------------------------------------------------------------------------- 332 333 SCI_STATUS scic_remote_device_destruct( 334 SCI_REMOTE_DEVICE_HANDLE_T remote_device 335 ) 336 { 337 SCIC_SDS_REMOTE_DEVICE_T *this_device; 338 this_device = (SCIC_SDS_REMOTE_DEVICE_T *)remote_device; 339 340 SCIC_LOG_TRACE(( 341 sci_base_object_get_logger(this_device), 342 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 343 SCIC_LOG_OBJECT_STP_REMOTE_TARGET | 344 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET, 345 "scic_remote_device_destruct(0x%x) enter\n", 346 remote_device 347 )); 348 349 return this_device->state_handlers->parent.destruct_handler(&this_device->parent); 350 } 351 352 // --------------------------------------------------------------------------- 353 354 #if !defined(DISABLE_WIDE_PORTED_TARGETS) 355 356 SCI_STATUS scic_remote_device_set_port_width( 357 SCI_REMOTE_DEVICE_HANDLE_T remote_device, 358 U8 new_port_width 359 ) 360 { 361 SCIC_SDS_REMOTE_DEVICE_T *this_device; 362 363 this_device = (SCIC_SDS_REMOTE_DEVICE_T *)remote_device; 364 365 SCIC_LOG_TRACE(( 366 sci_base_object_get_logger(this_device), 367 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 368 SCIC_LOG_OBJECT_STP_REMOTE_TARGET | 369 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET, 370 "scic_remote_device_set_port_width(0x%x, 0x%x) enter\n", 371 remote_device, new_port_width 372 )); 373 374 if(new_port_width != 0) 375 { 376 this_device->device_port_width = new_port_width; 377 378 return SCI_SUCCESS; 379 } 380 else 381 return SCI_FAILURE; 382 } 383 384 // --------------------------------------------------------------------------- 385 386 U8 scic_remote_device_get_port_width( 387 SCI_REMOTE_DEVICE_HANDLE_T remote_device 388 ) 389 { 390 SCIC_SDS_REMOTE_DEVICE_T *this_device; 391 392 this_device = (SCIC_SDS_REMOTE_DEVICE_T *)remote_device; 393 394 SCIC_LOG_TRACE(( 395 sci_base_object_get_logger(this_device), 396 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 397 SCIC_LOG_OBJECT_STP_REMOTE_TARGET | 398 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET, 399 "scic_remote_device_get_port_width(0x%x) enter\n", 400 remote_device 401 )); 402 403 return (U8)this_device->device_port_width; 404 } 405 406 #endif // !defined(DISABLE_WIDE_PORTED_TARGETS) 407 408 // --------------------------------------------------------------------------- 409 410 SCI_STATUS scic_remote_device_start( 411 SCI_REMOTE_DEVICE_HANDLE_T remote_device, 412 U32 timeout 413 ) 414 { 415 SCIC_SDS_REMOTE_DEVICE_T *this_device; 416 this_device = (SCIC_SDS_REMOTE_DEVICE_T *)remote_device; 417 418 SCIC_LOG_TRACE(( 419 sci_base_object_get_logger(this_device), 420 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 421 SCIC_LOG_OBJECT_STP_REMOTE_TARGET | 422 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET, 423 "scic_remote_device_start(0x%x, 0x%x) enter\n", 424 remote_device, timeout 425 )); 426 427 return this_device->state_handlers->parent.start_handler(&this_device->parent); 428 } 429 430 // --------------------------------------------------------------------------- 431 432 SCI_STATUS scic_remote_device_stop( 433 SCI_REMOTE_DEVICE_HANDLE_T remote_device, 434 U32 timeout 435 ) 436 { 437 SCIC_SDS_REMOTE_DEVICE_T *this_device; 438 this_device = (SCIC_SDS_REMOTE_DEVICE_T *)remote_device; 439 440 SCIC_LOG_TRACE(( 441 sci_base_object_get_logger(this_device), 442 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 443 SCIC_LOG_OBJECT_STP_REMOTE_TARGET | 444 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET, 445 "scic_remote_device_stop(0x%x, 0x%x) enter\n", 446 remote_device, timeout 447 )); 448 449 return this_device->state_handlers->parent.stop_handler(&this_device->parent); 450 } 451 452 /** 453 * This method invokes the remote device reset handler. 454 * 455 * @param[in] this_device The remote device for which the reset is being 456 * requested. 457 * 458 * @return SCI_STATUS 459 */ 460 SCI_STATUS scic_remote_device_reset( 461 SCI_REMOTE_DEVICE_HANDLE_T remote_device 462 ) 463 { 464 SCIC_SDS_REMOTE_DEVICE_T *this_device; 465 this_device = (SCIC_SDS_REMOTE_DEVICE_T *)remote_device; 466 467 SCIC_LOG_TRACE(( 468 sci_base_object_get_logger(this_device), 469 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 470 SCIC_LOG_OBJECT_STP_REMOTE_TARGET | 471 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET, 472 "scic_remote_device_reset(0x%x) enter\n", 473 remote_device 474 )); 475 476 return this_device->state_handlers->parent.reset_handler(&this_device->parent); 477 } 478 479 /** 480 * This method invokes the remote device reset handler. 481 * 482 * @param[in] this_device The remote device for which the reset is being 483 * requested. 484 * 485 * @return SCI_STATUS 486 */ 487 SCI_STATUS scic_remote_device_reset_complete( 488 SCI_REMOTE_DEVICE_HANDLE_T remote_device 489 ) 490 { 491 SCIC_SDS_REMOTE_DEVICE_T *this_device; 492 this_device = (SCIC_SDS_REMOTE_DEVICE_T *)remote_device; 493 494 SCIC_LOG_TRACE(( 495 sci_base_object_get_logger(this_device), 496 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 497 SCIC_LOG_OBJECT_STP_REMOTE_TARGET | 498 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET, 499 "scic_remote_device_reset_complete(0x%x) enter\n", 500 remote_device 501 )); 502 503 return this_device->state_handlers->parent.reset_complete_handler(&this_device->parent); 504 } 505 506 /** 507 * This method invokes the remote device reset handler. 508 * 509 * @param[in] this_device The remote device for which the reset is being 510 * requested. 511 * 512 * @return SCI_STATUS 513 */ 514 U32 scic_remote_device_get_suggested_reset_timeout( 515 SCI_REMOTE_DEVICE_HANDLE_T remote_device 516 ) 517 { 518 SCIC_SDS_REMOTE_DEVICE_T *this_device; 519 this_device = (SCIC_SDS_REMOTE_DEVICE_T *)remote_device; 520 521 SCIC_LOG_TRACE(( 522 sci_base_object_get_logger(this_device), 523 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 524 SCIC_LOG_OBJECT_STP_REMOTE_TARGET | 525 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET, 526 "scic_remote_device_get_suggested_reset_timeout(0x%x) enter\n", 527 remote_device 528 )); 529 530 if (this_device->target_protocols.u.bits.attached_stp_target) 531 { 532 return SCIC_SDS_SIGNATURE_FIS_TIMEOUT; 533 } 534 535 return SCIC_SDS_REMOTE_DEVICE_RESET_TIMEOUT; 536 } 537 538 // --------------------------------------------------------------------------- 539 540 SCI_STATUS scic_remote_device_set_max_connection_rate( 541 SCI_REMOTE_DEVICE_HANDLE_T remote_device, 542 SCI_SAS_LINK_RATE connection_rate 543 ) 544 { 545 SCIC_SDS_REMOTE_DEVICE_T *this_device; 546 this_device = (SCIC_SDS_REMOTE_DEVICE_T *)remote_device; 547 548 SCIC_LOG_TRACE(( 549 sci_base_object_get_logger(this_device), 550 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 551 SCIC_LOG_OBJECT_STP_REMOTE_TARGET | 552 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET, 553 "scic_remote_device_set_max_connection_rate(0x%x, 0x%x) enter\n", 554 remote_device, connection_rate 555 )); 556 557 this_device->connection_rate = connection_rate; 558 559 return SCI_SUCCESS; 560 } 561 562 // --------------------------------------------------------------------------- 563 564 SCI_SAS_LINK_RATE scic_remote_device_get_connection_rate( 565 SCI_REMOTE_DEVICE_HANDLE_T remote_device 566 ) 567 { 568 SCIC_SDS_REMOTE_DEVICE_T *this_device; 569 this_device = (SCIC_SDS_REMOTE_DEVICE_T *)remote_device; 570 571 SCIC_LOG_TRACE(( 572 sci_base_object_get_logger(this_device), 573 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 574 SCIC_LOG_OBJECT_STP_REMOTE_TARGET | 575 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET, 576 "scic_remote_device_get_connection_rate(0x%x) enter\n", 577 remote_device 578 )); 579 580 return this_device->connection_rate; 581 } 582 583 // --------------------------------------------------------------------------- 584 585 void scic_remote_device_get_protocols( 586 SCI_REMOTE_DEVICE_HANDLE_T remote_device, 587 SMP_DISCOVER_RESPONSE_PROTOCOLS_T * protocols 588 ) 589 { 590 SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *) 591 remote_device; 592 593 SCIC_LOG_TRACE(( 594 sci_base_object_get_logger(this_device), 595 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 596 SCIC_LOG_OBJECT_STP_REMOTE_TARGET | 597 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET, 598 "scic_remote_device_get_protocols(0x%x) enter\n", 599 remote_device 600 )); 601 602 protocols->u.all = this_device->target_protocols.u.all; 603 } 604 605 // --------------------------------------------------------------------------- 606 607 void scic_remote_device_get_sas_address( 608 SCI_REMOTE_DEVICE_HANDLE_T remote_device, 609 SCI_SAS_ADDRESS_T * sas_address 610 ) 611 { 612 SCIC_SDS_REMOTE_DEVICE_T *this_device; 613 this_device = (SCIC_SDS_REMOTE_DEVICE_T *)remote_device; 614 615 SCIC_LOG_TRACE(( 616 sci_base_object_get_logger(this_device), 617 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 618 SCIC_LOG_OBJECT_STP_REMOTE_TARGET | 619 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET, 620 "scic_remote_device_get_sas_address(0x%x, 0x%x) enter\n", 621 remote_device, sas_address 622 )); 623 624 sas_address->low = this_device->device_address.low; 625 sas_address->high = this_device->device_address.high; 626 } 627 628 // --------------------------------------------------------------------------- 629 #if !defined(DISABLE_ATAPI) 630 BOOL scic_remote_device_is_atapi( 631 SCI_REMOTE_DEVICE_HANDLE_T device_handle 632 ) 633 { 634 return ((SCIC_SDS_REMOTE_DEVICE_T *)device_handle)->is_atapi; 635 } 636 #endif 637 638 639 //***************************************************************************** 640 //* SCU DRIVER STANDARD (SDS) REMOTE DEVICE IMPLEMENTATIONS 641 //***************************************************************************** 642 643 /** 644 * Remote device timer requirements 645 */ 646 #define SCIC_SDS_REMOTE_DEVICE_MINIMUM_TIMER_COUNT (0) 647 #define SCIC_SDS_REMOTE_DEVICE_MAXIMUM_TIMER_COUNT (SCI_MAX_REMOTE_DEVICES) 648 649 /** 650 * @brief This method returns the minimum number of timers required for all 651 * remote devices. 652 * 653 * @return U32 654 */ 655 U32 scic_sds_remote_device_get_min_timer_count(void) 656 { 657 return SCIC_SDS_REMOTE_DEVICE_MINIMUM_TIMER_COUNT; 658 } 659 660 /** 661 * @brief This method returns the maximum number of timers requried for all 662 * remote devices. 663 * 664 * @return U32 665 */ 666 U32 scic_sds_remote_device_get_max_timer_count(void) 667 { 668 return SCIC_SDS_REMOTE_DEVICE_MAXIMUM_TIMER_COUNT; 669 } 670 671 // --------------------------------------------------------------------------- 672 673 #ifdef SCI_LOGGING 674 /** 675 * This method will enable and turn on state transition logging for the remote 676 * device object. 677 * 678 * @param[in] this_device The device for which state transition logging is to 679 * be enabled. 680 * 681 * @return Nothing 682 */ 683 void scic_sds_remote_device_initialize_state_logging( 684 SCIC_SDS_REMOTE_DEVICE_T *this_device 685 ) 686 { 687 sci_base_state_machine_logger_initialize( 688 &this_device->parent.state_machine_logger, 689 &this_device->parent.state_machine, 690 &this_device->parent.parent, 691 scic_cb_logger_log_states, 692 "SCIC_SDS_REMOTE_DEVICE_T", "base state machine", 693 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 694 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 695 SCIC_LOG_OBJECT_STP_REMOTE_TARGET 696 ); 697 698 if (this_device->has_ready_substate_machine) 699 { 700 sci_base_state_machine_logger_initialize( 701 &this_device->ready_substate_machine_logger, 702 &this_device->ready_substate_machine, 703 &this_device->parent.parent, 704 scic_cb_logger_log_states, 705 "SCIC_SDS_REMOTE_DEVICE_T", "ready substate machine", 706 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 707 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 708 SCIC_LOG_OBJECT_STP_REMOTE_TARGET 709 ); 710 } 711 } 712 713 /** 714 * This method will stop the state machine logging for this object and should 715 * be called before the object is destroyed. 716 * 717 * @param[in] this_device The device on which to stop logging state 718 * transitions. 719 * 720 * @return Nothing 721 */ 722 void scic_sds_remote_device_deinitialize_state_logging( 723 SCIC_SDS_REMOTE_DEVICE_T *this_device 724 ) 725 { 726 sci_base_state_machine_logger_deinitialize( 727 &this_device->parent.state_machine_logger, 728 &this_device->parent.state_machine 729 ); 730 731 if (this_device->has_ready_substate_machine) 732 { 733 sci_base_state_machine_logger_deinitialize( 734 &this_device->ready_substate_machine_logger, 735 &this_device->ready_substate_machine 736 ); 737 } 738 } 739 #endif 740 741 /** 742 * This method invokes the remote device suspend state handler. 743 * 744 * @param[in] this_device The remote device for which the suspend is being 745 * requested. 746 * 747 * @return SCI_STATUS 748 */ 749 SCI_STATUS scic_sds_remote_device_suspend( 750 SCIC_SDS_REMOTE_DEVICE_T *this_device, 751 U32 suspend_type 752 ) 753 { 754 return this_device->state_handlers->suspend_handler(this_device, suspend_type); 755 } 756 757 /** 758 * This method invokes the remote device resume state handler. 759 * 760 * @param[in] this_device The remote device for which the resume is being 761 * requested. 762 * 763 * @return SCI_STATUS 764 */ 765 SCI_STATUS scic_sds_remote_device_resume( 766 SCIC_SDS_REMOTE_DEVICE_T *this_device 767 ) 768 { 769 return this_device->state_handlers->resume_handler(this_device); 770 } 771 772 /** 773 * This method invokes the frame handler for the remote device state machine 774 * 775 * @param[in] this_device The remote device for which the event handling is 776 * being requested. 777 * @param[in] frame_index This is the frame index that is being processed. 778 * 779 * @return SCI_STATUS 780 */ 781 SCI_STATUS scic_sds_remote_device_frame_handler( 782 SCIC_SDS_REMOTE_DEVICE_T *this_device, 783 U32 frame_index 784 ) 785 { 786 return this_device->state_handlers->frame_handler(this_device, frame_index); 787 } 788 789 /** 790 * This method invokes the remote device event handler. 791 * 792 * @param[in] this_device The remote device for which the event handling is 793 * being requested. 794 * @param[in] event_code This is the event code that is to be processed. 795 * 796 * @return SCI_STATUS 797 */ 798 SCI_STATUS scic_sds_remote_device_event_handler( 799 SCIC_SDS_REMOTE_DEVICE_T *this_device, 800 U32 event_code 801 ) 802 { 803 return this_device->state_handlers->event_handler(this_device, event_code); 804 } 805 806 /** 807 * This method invokes the remote device start io handler. 808 * 809 * @param[in] controller The controller that is starting the io request. 810 * @param[in] this_device The remote device for which the start io handling is 811 * being requested. 812 * @param[in] io_request The io request that is being started. 813 * 814 * @return SCI_STATUS 815 */ 816 SCI_STATUS scic_sds_remote_device_start_io( 817 SCIC_SDS_CONTROLLER_T *controller, 818 SCIC_SDS_REMOTE_DEVICE_T *this_device, 819 SCIC_SDS_REQUEST_T *io_request 820 ) 821 { 822 return this_device->state_handlers->parent.start_io_handler( 823 &this_device->parent, &io_request->parent); 824 } 825 826 /** 827 * This method invokes the remote device complete io handler. 828 * 829 * @param[in] controller The controller that is completing the io request. 830 * @param[in] this_device The remote device for which the complete io handling 831 * is being requested. 832 * @param[in] io_request The io request that is being completed. 833 * 834 * @return SCI_STATUS 835 */ 836 SCI_STATUS scic_sds_remote_device_complete_io( 837 SCIC_SDS_CONTROLLER_T *controller, 838 SCIC_SDS_REMOTE_DEVICE_T *this_device, 839 SCIC_SDS_REQUEST_T *io_request 840 ) 841 { 842 return this_device->state_handlers->parent.complete_io_handler( 843 &this_device->parent, &io_request->parent); 844 } 845 846 /** 847 * This method invokes the remote device start task handler. 848 * 849 * @param[in] controller The controller that is starting the task request. 850 * @param[in] this_device The remote device for which the start task handling 851 * is being requested. 852 * @param[in] io_request The task request that is being started. 853 * 854 * @return SCI_STATUS 855 */ 856 SCI_STATUS scic_sds_remote_device_start_task( 857 SCIC_SDS_CONTROLLER_T *controller, 858 SCIC_SDS_REMOTE_DEVICE_T *this_device, 859 SCIC_SDS_REQUEST_T *io_request 860 ) 861 { 862 return this_device->state_handlers->parent.start_task_handler( 863 &this_device->parent, &io_request->parent); 864 } 865 866 /** 867 * This method takes the request and bulids an appropriate SCU context for the 868 * request and then requests the controller to post the request. 869 * 870 * @param[in] this_device 871 * @param[in] request 872 * 873 * @return none 874 */ 875 void scic_sds_remote_device_post_request( 876 SCIC_SDS_REMOTE_DEVICE_T * this_device, 877 U32 request 878 ) 879 { 880 U32 context; 881 882 context = scic_sds_remote_device_build_command_context(this_device, request); 883 884 scic_sds_controller_post_request( 885 scic_sds_remote_device_get_controller(this_device), 886 context 887 ); 888 } 889 890 #if !defined(DISABLE_ATAPI) 891 /** 892 * This method check the signature fis of a stp device to decide whether 893 * a device is atapi or not. 894 * 895 * @param[in] this_device The device to be checked. 896 * 897 * @return TRUE if a device is atapi device. False if a device is not atapi. 898 */ 899 BOOL scic_sds_remote_device_is_atapi( 900 SCIC_SDS_REMOTE_DEVICE_T * this_device 901 ) 902 { 903 if (!this_device->target_protocols.u.bits.attached_stp_target) 904 return FALSE; 905 else if (this_device->is_direct_attached) 906 { 907 SCIC_SDS_PHY_T * phy; 908 SCIC_SATA_PHY_PROPERTIES_T properties; 909 SATA_FIS_REG_D2H_T * signature_fis; 910 phy = scic_sds_port_get_a_connected_phy(this_device->owning_port); 911 scic_sata_phy_get_properties(phy, &properties); 912 913 //decode the signature fis. 914 signature_fis = &(properties.signature_fis); 915 916 if ( (signature_fis->sector_count == 0x01) 917 && (signature_fis->lba_low == 0x01) 918 && (signature_fis->lba_mid == 0x14) 919 && (signature_fis->lba_high == 0xEB) 920 && ( (signature_fis->device & 0x5F) == 0x00) 921 ) 922 { 923 // An ATA device supporting the PACKET command set. 924 return TRUE; 925 } 926 else 927 return FALSE; 928 } 929 else 930 { 931 //Expander supported ATAPI device is not currently supported. 932 return FALSE; 933 } 934 } 935 936 #endif // !defined(DISABLE_ATAPI) 937 938 //****************************************************************************** 939 //* REMOTE DEVICE STATE MACHINE 940 //****************************************************************************** 941 942 /** 943 * This method is called once the remote node context is ready to be 944 * freed. The remote device can now report that its stop operation is 945 * complete. 946 * 947 * @param[in] user_parameter This is cast to a remote device object. 948 * 949 * @return none 950 */ 951 static 952 void scic_sds_cb_remote_device_rnc_destruct_complete( 953 void * user_parameter 954 ) 955 { 956 SCIC_SDS_REMOTE_DEVICE_T * this_device; 957 this_device = (SCIC_SDS_REMOTE_DEVICE_T *)user_parameter; 958 959 ASSERT(this_device->started_request_count == 0); 960 961 sci_base_state_machine_change_state( 962 scic_sds_remote_device_get_base_state_machine(this_device), 963 SCI_BASE_REMOTE_DEVICE_STATE_STOPPED 964 ); 965 } 966 967 /** 968 * This method is called once the remote node context has transisitioned to a 969 * ready state. This is the indication that the remote device object can also 970 * transition to ready. 971 * 972 * @param[in] user_parameter This is cast to a remote device object. 973 * 974 * @return none 975 */ 976 static 977 void scic_sds_remote_device_resume_complete_handler( 978 void * user_parameter 979 ) 980 { 981 SCIC_SDS_REMOTE_DEVICE_T * this_device; 982 this_device = (SCIC_SDS_REMOTE_DEVICE_T *)user_parameter; 983 984 if ( 985 sci_base_state_machine_get_state(&this_device->parent.state_machine) 986 != SCI_BASE_REMOTE_DEVICE_STATE_READY 987 ) 988 { 989 sci_base_state_machine_change_state( 990 &this_device->parent.state_machine, 991 SCI_BASE_REMOTE_DEVICE_STATE_READY 992 ); 993 } 994 } 995 996 /** 997 * This method will perform the STP request start processing common 998 * to IO requests and task requests of all types. 999 * 1000 * @param[in] device This parameter specifies the device for which the 1001 * request is being started. 1002 * @param[in] request This parameter specifies the request being started. 1003 * @param[in] status This parameter specifies the current start operation 1004 * status. 1005 * 1006 * @return none 1007 */ 1008 void scic_sds_remote_device_start_request( 1009 SCIC_SDS_REMOTE_DEVICE_T * this_device, 1010 SCIC_SDS_REQUEST_T * the_request, 1011 SCI_STATUS status 1012 ) 1013 { 1014 // We still have a fault in starting the io complete it on the port 1015 if (status == SCI_SUCCESS) 1016 scic_sds_remote_device_increment_request_count(this_device); 1017 else 1018 { 1019 this_device->owning_port->state_handlers->complete_io_handler( 1020 this_device->owning_port, this_device, the_request 1021 ); 1022 } 1023 } 1024 1025 1026 /** 1027 * This method will continue to post tc for a STP request. This method usually 1028 * serves as a callback when RNC gets resumed during a task management sequence. 1029 * 1030 * @param[in] request This parameter specifies the request being continued. 1031 * 1032 * @return none 1033 */ 1034 void scic_sds_remote_device_continue_request( 1035 SCIC_SDS_REMOTE_DEVICE_T * this_device 1036 ) 1037 { 1038 // we need to check if this request is still valid to continue. 1039 if (this_device->working_request != NULL) 1040 { 1041 SCIC_SDS_REQUEST_T * this_request = this_device->working_request; 1042 1043 this_request->owning_controller->state_handlers->parent.continue_io_handler( 1044 &this_request->owning_controller->parent, 1045 &this_request->target_device->parent, 1046 &this_request->parent 1047 ); 1048 } 1049 } 1050 1051 /** 1052 * @brief This method will terminate all of the IO requests in the 1053 * controllers IO request table that were targeted for this 1054 * device. 1055 * 1056 * @param[in] this_device This parameter specifies the remote device 1057 * for which to attempt to terminate all requests. 1058 * 1059 * @return This method returns an indication as to whether all requests 1060 * were successfully terminated. If a single request fails to 1061 * be terminated, then this method will return the failure. 1062 */ 1063 static 1064 SCI_STATUS scic_sds_remote_device_terminate_requests( 1065 SCIC_SDS_REMOTE_DEVICE_T *this_device 1066 ) 1067 { 1068 return scic_sds_terminate_reqests( 1069 this_device->owning_port->owning_controller, 1070 this_device, 1071 NULL); 1072 } 1073 1074 //***************************************************************************** 1075 //* DEFAULT STATE HANDLERS 1076 //***************************************************************************** 1077 1078 /** 1079 * This method is the default start handler. It logs a warning and returns a 1080 * failure. 1081 * 1082 * @param[in] device The SCI_BASE_REMOTE_DEVICE which is then cast into a 1083 * SCIC_SDS_REMOTE_DEVICE. 1084 * 1085 * @return SCI_STATUS 1086 * @retval SCI_FAILURE_INVALID_STATE 1087 */ 1088 SCI_STATUS scic_sds_remote_device_default_start_handler( 1089 SCI_BASE_REMOTE_DEVICE_T *device 1090 ) 1091 { 1092 SCIC_LOG_WARNING(( 1093 sci_base_object_get_logger((SCIC_SDS_REMOTE_DEVICE_T *)device), 1094 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 1095 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 1096 SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 1097 "SCIC Remote Device requested to start while in wrong state %d\n", 1098 sci_base_state_machine_get_state( 1099 scic_sds_remote_device_get_base_state_machine((SCIC_SDS_REMOTE_DEVICE_T *)device)) 1100 )); 1101 1102 return SCI_FAILURE_INVALID_STATE; 1103 } 1104 1105 /** 1106 * This method is the default stop handler. It logs a warning and returns a 1107 * failure. 1108 * 1109 * @param[in] device The SCI_BASE_REMOTE_DEVICE which is then cast into a 1110 * SCIC_SDS_REMOTE_DEVICE. 1111 * 1112 * @return SCI_STATUS 1113 * @retval SCI_FAILURE_INVALID_STATE 1114 */ 1115 SCI_STATUS scic_sds_remote_device_default_stop_handler( 1116 SCI_BASE_REMOTE_DEVICE_T *device 1117 ) 1118 { 1119 SCIC_LOG_WARNING(( 1120 sci_base_object_get_logger((SCIC_SDS_REMOTE_DEVICE_T *)device), 1121 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 1122 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 1123 SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 1124 "SCIC Remote Device requested to stop while in wrong state %d\n", 1125 sci_base_state_machine_get_state( 1126 scic_sds_remote_device_get_base_state_machine((SCIC_SDS_REMOTE_DEVICE_T *)device)) 1127 )); 1128 1129 return SCI_FAILURE_INVALID_STATE; 1130 } 1131 1132 /** 1133 * This method is the default fail handler. It logs a warning and returns a 1134 * failure. 1135 * 1136 * @param[in] device The SCI_BASE_REMOTE_DEVICE which is then cast into a 1137 * SCIC_SDS_REMOTE_DEVICE. 1138 * 1139 * @return SCI_STATUS 1140 * @retval SCI_FAILURE_INVALID_STATE 1141 */ 1142 SCI_STATUS scic_sds_remote_device_default_fail_handler( 1143 SCI_BASE_REMOTE_DEVICE_T *device 1144 ) 1145 { 1146 SCIC_LOG_WARNING(( 1147 sci_base_object_get_logger((SCIC_SDS_REMOTE_DEVICE_T *)device), 1148 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 1149 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 1150 SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 1151 "SCIC Remote Device requested to fail while in wrong state %d\n", 1152 sci_base_state_machine_get_state( 1153 scic_sds_remote_device_get_base_state_machine((SCIC_SDS_REMOTE_DEVICE_T *)device)) 1154 )); 1155 1156 return SCI_FAILURE_INVALID_STATE; 1157 } 1158 1159 /** 1160 * This method is the default destruct handler. It logs a warning and returns 1161 * a failure. 1162 * 1163 * @param[in] device The SCI_BASE_REMOTE_DEVICE which is then cast into a 1164 * SCIC_SDS_REMOTE_DEVICE. 1165 * 1166 * @return SCI_STATUS 1167 * @retval SCI_FAILURE_INVALID_STATE 1168 */ 1169 SCI_STATUS scic_sds_remote_device_default_destruct_handler( 1170 SCI_BASE_REMOTE_DEVICE_T *device 1171 ) 1172 { 1173 SCIC_LOG_WARNING(( 1174 sci_base_object_get_logger((SCIC_SDS_REMOTE_DEVICE_T *)device), 1175 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 1176 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 1177 SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 1178 "SCIC Remote Device requested to destroy while in wrong state %d\n", 1179 sci_base_state_machine_get_state( 1180 scic_sds_remote_device_get_base_state_machine((SCIC_SDS_REMOTE_DEVICE_T *)device)) 1181 )); 1182 1183 return SCI_FAILURE_INVALID_STATE; 1184 } 1185 1186 /** 1187 * This method is the default reset handler. It logs a warning and returns a 1188 * failure. 1189 * 1190 * @param[in] device The SCI_BASE_REMOTE_DEVICE which is then cast into a 1191 * SCIC_SDS_REMOTE_DEVICE. 1192 * 1193 * @return SCI_STATUS 1194 * @retval SCI_FAILURE_INVALID_STATE 1195 */ 1196 SCI_STATUS scic_sds_remote_device_default_reset_handler( 1197 SCI_BASE_REMOTE_DEVICE_T *device 1198 ) 1199 { 1200 SCIC_LOG_WARNING(( 1201 sci_base_object_get_logger((SCIC_SDS_REMOTE_DEVICE_T *)device), 1202 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 1203 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 1204 SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 1205 "SCIC Remote Device requested to reset while in wrong state %d\n", 1206 sci_base_state_machine_get_state( 1207 scic_sds_remote_device_get_base_state_machine((SCIC_SDS_REMOTE_DEVICE_T *)device)) 1208 )); 1209 1210 return SCI_FAILURE_INVALID_STATE; 1211 } 1212 1213 /** 1214 * This method is the default reset complete handler. It logs a warning and 1215 * returns a failure. 1216 * 1217 * @param[in] device The SCI_BASE_REMOTE_DEVICE which is then cast into a 1218 * SCIC_SDS_REMOTE_DEVICE. 1219 * 1220 * @return SCI_STATUS 1221 * @retval SCI_FAILURE_INVALID_STATE 1222 */ 1223 SCI_STATUS scic_sds_remote_device_default_reset_complete_handler( 1224 SCI_BASE_REMOTE_DEVICE_T *device 1225 ) 1226 { 1227 SCIC_LOG_WARNING(( 1228 sci_base_object_get_logger((SCIC_SDS_REMOTE_DEVICE_T *)device), 1229 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 1230 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 1231 SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 1232 "SCIC Remote Device requested to complete reset while in wrong state %d\n", 1233 sci_base_state_machine_get_state( 1234 scic_sds_remote_device_get_base_state_machine((SCIC_SDS_REMOTE_DEVICE_T *)device)) 1235 )); 1236 1237 return SCI_FAILURE_INVALID_STATE; 1238 } 1239 1240 /** 1241 * This method is the default suspend handler. It logs a warning and returns 1242 * a failure. 1243 * 1244 * @param[in] device The SCI_BASE_REMOTE_DEVICE which is then cast into a 1245 * SCIC_SDS_REMOTE_DEVICE. 1246 * 1247 * @return SCI_STATUS 1248 * @retval SCI_FAILURE_INVALID_STATE 1249 */ 1250 SCI_STATUS scic_sds_remote_device_default_suspend_handler( 1251 SCIC_SDS_REMOTE_DEVICE_T *this_device, 1252 U32 suspend_type 1253 ) 1254 { 1255 SCIC_LOG_WARNING(( 1256 sci_base_object_get_logger(this_device), 1257 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 1258 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 1259 SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 1260 "SCIC Remote Device 0x%x requested to suspend %d while in wrong state %d\n", 1261 this_device, suspend_type, 1262 sci_base_state_machine_get_state( 1263 scic_sds_remote_device_get_base_state_machine(this_device)) 1264 )); 1265 1266 return SCI_FAILURE_INVALID_STATE; 1267 } 1268 1269 /** 1270 * This method is the default resume handler. It logs a warning and returns a 1271 * failure. 1272 * 1273 * @param[in] device The SCI_BASE_REMOTE_DEVICE which is then cast into a 1274 * SCIC_SDS_REMOTE_DEVICE. 1275 * 1276 * @return SCI_STATUS 1277 * @retval SCI_FAILURE_INVALID_STATE 1278 */ 1279 SCI_STATUS scic_sds_remote_device_default_resume_handler( 1280 SCIC_SDS_REMOTE_DEVICE_T *this_device 1281 ) 1282 { 1283 SCIC_LOG_WARNING(( 1284 sci_base_object_get_logger(this_device), 1285 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 1286 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 1287 SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 1288 "SCIC Remote Device requested to resume while in wrong state %d\n", 1289 sci_base_state_machine_get_state( 1290 scic_sds_remote_device_get_base_state_machine(this_device)) 1291 )); 1292 1293 return SCI_FAILURE_INVALID_STATE; 1294 } 1295 1296 #if defined(SCI_LOGGING) 1297 /** 1298 * This is a private method for emitting log messages related to events reported 1299 * to the remote device from the controller object. 1300 * 1301 * @param [in] this_device This is the device object that is receiving the 1302 * event. 1303 * @param [in] event_code The event code to process. 1304 * 1305 * @return None 1306 */ 1307 static void scic_sds_emit_event_log_message( 1308 SCIC_SDS_REMOTE_DEVICE_T * this_device, 1309 U32 event_code, 1310 char * message_guts, 1311 BOOL ready_state 1312 ) 1313 { 1314 SCIC_LOG_WARNING(( 1315 sci_base_object_get_logger(this_device), 1316 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 1317 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 1318 SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 1319 "SCIC Remote device 0x%x (state %d) received %s %x while in the %sready %s%d\n", 1320 this_device, 1321 sci_base_state_machine_get_state( 1322 scic_sds_remote_device_get_base_state_machine(this_device)), 1323 message_guts, event_code, 1324 (ready_state) 1325 ? "" 1326 : "not ", 1327 (this_device->has_ready_substate_machine) 1328 ? "substate " 1329 : "", 1330 (this_device->has_ready_substate_machine) 1331 ? sci_base_state_machine_get_state(&this_device->ready_substate_machine) 1332 : 0 1333 )); 1334 } 1335 #else // defined(SCI_LOGGING) 1336 #define scic_sds_emit_event_log_message(device, event_code, message, state) 1337 #endif // defined(SCI_LOGGING) 1338 1339 /** 1340 * This method is the default event handler. It will call the RNC state 1341 * machine handler for any RNC events otherwise it will log a warning and 1342 * returns a failure. 1343 * 1344 * @param[in] device The SCI_BASE_REMOTE_DEVICE which is then cast into a 1345 * SCIC_SDS_REMOTE_DEVICE. 1346 * @param[in] event_code The event code that the SCIC_SDS_CONTROLLER wants the 1347 * device object to process. 1348 * 1349 * @return SCI_STATUS 1350 * @retval SCI_FAILURE_INVALID_STATE 1351 */ 1352 static 1353 SCI_STATUS scic_sds_remote_device_core_event_handler( 1354 SCIC_SDS_REMOTE_DEVICE_T *this_device, 1355 U32 event_code, 1356 BOOL is_ready_state 1357 ) 1358 { 1359 SCI_STATUS status; 1360 1361 switch (scu_get_event_type(event_code)) 1362 { 1363 case SCU_EVENT_TYPE_RNC_OPS_MISC: 1364 case SCU_EVENT_TYPE_RNC_SUSPEND_TX: 1365 case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX: 1366 status = scic_sds_remote_node_context_event_handler(this_device->rnc, event_code); 1367 break; 1368 case SCU_EVENT_TYPE_PTX_SCHEDULE_EVENT: 1369 1370 if( scu_get_event_code(event_code) == SCU_EVENT_IT_NEXUS_TIMEOUT ) 1371 { 1372 status = SCI_SUCCESS; 1373 1374 // Suspend the associated RNC 1375 scic_sds_remote_node_context_suspend( this_device->rnc, 1376 SCI_SOFTWARE_SUSPENSION, 1377 NULL, NULL ); 1378 1379 scic_sds_emit_event_log_message( 1380 this_device, event_code, 1381 (is_ready_state) 1382 ? "I_T_Nexus_Timeout event" 1383 : "I_T_Nexus_Timeout event in wrong state", 1384 is_ready_state ); 1385 1386 break; 1387 } 1388 // Else, fall through and treat as unhandled... 1389 1390 default: 1391 scic_sds_emit_event_log_message( this_device, event_code, 1392 (is_ready_state) 1393 ? "unexpected event" 1394 : "unexpected event in wrong state", 1395 is_ready_state ); 1396 status = SCI_FAILURE_INVALID_STATE; 1397 break; 1398 } 1399 1400 return status; 1401 } 1402 /** 1403 * This method is the default event handler. It will call the RNC state 1404 * machine handler for any RNC events otherwise it will log a warning and 1405 * returns a failure. 1406 * 1407 * @param[in] device The SCI_BASE_REMOTE_DEVICE which is then cast into a 1408 * SCIC_SDS_REMOTE_DEVICE. 1409 * @param[in] event_code The event code that the SCIC_SDS_CONTROLLER wants the 1410 * device object to process. 1411 * 1412 * @return SCI_STATUS 1413 * @retval SCI_FAILURE_INVALID_STATE 1414 */ 1415 SCI_STATUS scic_sds_remote_device_default_event_handler( 1416 SCIC_SDS_REMOTE_DEVICE_T *this_device, 1417 U32 event_code 1418 ) 1419 { 1420 return scic_sds_remote_device_core_event_handler( this_device, 1421 event_code, 1422 FALSE ); 1423 } 1424 1425 /** 1426 * This method is the default unsolicited frame handler. It logs a warning, 1427 * releases the frame and returns a failure. 1428 * 1429 * @param[in] device The SCI_BASE_REMOTE_DEVICE which is then cast into a 1430 * SCIC_SDS_REMOTE_DEVICE. 1431 * @param[in] frame_index The frame index for which the SCIC_SDS_CONTROLLER 1432 * wants this device object to process. 1433 * 1434 * @return SCI_STATUS 1435 * @retval SCI_FAILURE_INVALID_STATE 1436 */ 1437 SCI_STATUS scic_sds_remote_device_default_frame_handler( 1438 SCIC_SDS_REMOTE_DEVICE_T *this_device, 1439 U32 frame_index 1440 ) 1441 { 1442 SCIC_LOG_WARNING(( 1443 sci_base_object_get_logger(this_device), 1444 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 1445 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 1446 SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 1447 "SCIC Remote Device requested to handle frame %x while in wrong state %d\n", 1448 frame_index, 1449 sci_base_state_machine_get_state(&this_device->parent.state_machine) 1450 )); 1451 1452 // Return the frame back to the controller 1453 scic_sds_controller_release_frame( 1454 scic_sds_remote_device_get_controller(this_device), frame_index 1455 ); 1456 1457 return SCI_FAILURE_INVALID_STATE; 1458 } 1459 1460 /** 1461 * This method is the default start io handler. It logs a warning and returns 1462 * a failure. 1463 * 1464 * @param[in] device The SCI_BASE_REMOTE_DEVICE which is then cast into a 1465 * SCIC_SDS_REMOTE_DEVICE. 1466 * @param[in] request The SCI_BASE_REQUEST which is then cast into a 1467 * SCIC_SDS_IO_REQUEST to start. 1468 * 1469 * @return SCI_STATUS 1470 * @retval SCI_FAILURE_INVALID_STATE 1471 */ 1472 SCI_STATUS scic_sds_remote_device_default_start_request_handler( 1473 SCI_BASE_REMOTE_DEVICE_T *device, 1474 SCI_BASE_REQUEST_T *request 1475 ) 1476 { 1477 SCIC_LOG_WARNING(( 1478 sci_base_object_get_logger((SCIC_SDS_REMOTE_DEVICE_T *)device), 1479 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 1480 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 1481 SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 1482 "SCIC Remote Device requested to start io request %x while in wrong state %d\n", 1483 request, 1484 sci_base_state_machine_get_state( 1485 scic_sds_remote_device_get_base_state_machine((SCIC_SDS_REMOTE_DEVICE_T *)device)) 1486 )); 1487 1488 return SCI_FAILURE_INVALID_STATE; 1489 } 1490 1491 /** 1492 * This method is the default complete io handler. It logs a warning and 1493 * returns a failure. 1494 * 1495 * @param[in] device The SCI_BASE_REMOTE_DEVICE which is then cast into a 1496 * SCIC_SDS_REMOTE_DEVICE. 1497 * @param[in] request The SCI_BASE_REQUEST which is then cast into a 1498 * SCIC_SDS_IO_REQUEST to complete. 1499 * 1500 * 1501 * @return SCI_STATUS 1502 * @retval SCI_FAILURE_INVALID_STATE 1503 */ 1504 SCI_STATUS scic_sds_remote_device_default_complete_request_handler( 1505 SCI_BASE_REMOTE_DEVICE_T *device, 1506 SCI_BASE_REQUEST_T *request 1507 ) 1508 { 1509 SCIC_LOG_WARNING(( 1510 sci_base_object_get_logger((SCIC_SDS_REMOTE_DEVICE_T *)device), 1511 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 1512 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 1513 SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 1514 "SCIC Remote Device requested to complete io_request %x while in wrong state %d\n", 1515 request, 1516 sci_base_state_machine_get_state( 1517 scic_sds_remote_device_get_base_state_machine((SCIC_SDS_REMOTE_DEVICE_T *)device)) 1518 )); 1519 1520 return SCI_FAILURE_INVALID_STATE; 1521 } 1522 1523 /** 1524 * This method is the default continue io handler. It logs a warning and 1525 * returns a failure. 1526 * 1527 * @param[in] device The SCI_BASE_REMOTE_DEVICE which is then cast into a 1528 * SCIC_SDS_REMOTE_DEVICE. 1529 * @param[in] request The SCI_BASE_REQUEST which is then cast into a 1530 * SCIC_SDS_IO_REQUEST to continue. 1531 * 1532 * @return SCI_STATUS 1533 * @retval SCI_FAILURE_INVALID_STATE 1534 */ 1535 SCI_STATUS scic_sds_remote_device_default_continue_request_handler( 1536 SCI_BASE_REMOTE_DEVICE_T *device, 1537 SCI_BASE_REQUEST_T *request 1538 ) 1539 { 1540 SCIC_LOG_WARNING(( 1541 sci_base_object_get_logger((SCIC_SDS_REMOTE_DEVICE_T *)device), 1542 SCIC_LOG_OBJECT_SSP_REMOTE_TARGET | 1543 SCIC_LOG_OBJECT_SMP_REMOTE_TARGET | 1544 SCIC_LOG_OBJECT_STP_REMOTE_TARGET, 1545 "SCIC Remote Device requested to continue io request %x while in wrong state %d\n", 1546 request, 1547 sci_base_state_machine_get_state( 1548 scic_sds_remote_device_get_base_state_machine((SCIC_SDS_REMOTE_DEVICE_T *)device)) 1549 )); 1550 1551 return SCI_FAILURE_INVALID_STATE; 1552 } 1553 1554 /** 1555 * This method is the general suspend handler. 1556 * 1557 * @param[in] device The SCI_BASE_REMOTE_DEVICE which is then cast into a 1558 * SCIC_SDS_REMOTE_DEVICE. 1559 * 1560 * @return SCI_STATUS 1561 * @retval SCI_FAILURE_INVALID_STATE 1562 */ 1563 static 1564 SCI_STATUS scic_sds_remote_device_general_suspend_handler( 1565 SCIC_SDS_REMOTE_DEVICE_T *this_device, 1566 U32 suspend_type 1567 ) 1568 { 1569 return scic_sds_remote_node_context_suspend(this_device->rnc, suspend_type, NULL, NULL); 1570 } 1571 1572 /** 1573 * This method is the general suspend handler. It logs a warning and returns 1574 * a failure. 1575 * 1576 * @param[in] device The SCI_BASE_REMOTE_DEVICE which is then cast into a 1577 * SCIC_SDS_REMOTE_DEVICE. 1578 * 1579 * @return SCI_STATUS 1580 * @retval SCI_FAILURE_INVALID_STATE 1581 */ 1582 static 1583 SCI_STATUS scic_sds_remote_device_general_resume_handler( 1584 SCIC_SDS_REMOTE_DEVICE_T *this_device 1585 ) 1586 { 1587 return scic_sds_remote_node_context_resume(this_device->rnc, NULL, NULL); 1588 } 1589 1590 //***************************************************************************** 1591 //* NORMAL STATE HANDLERS 1592 //***************************************************************************** 1593 1594 /** 1595 * This method is a general ssp frame handler. In most cases the device 1596 * object needs to route the unsolicited frame processing to the io request 1597 * object. This method decodes the tag for the io request object and routes 1598 * the unsolicited frame to that object. 1599 * 1600 * @param[in] device The SCI_BASE_REMOTE_DEVICE which is then cast into a 1601 * SCIC_SDS_REMOTE_DEVICE. 1602 * @param[in] frame_index The frame index for which the SCIC_SDS_CONTROLLER 1603 * wants this device object to process. 1604 * 1605 * @return SCI_STATUS 1606 * @retval SCI_FAILURE_INVALID_STATE 1607 */ 1608 SCI_STATUS scic_sds_remote_device_general_frame_handler( 1609 SCIC_SDS_REMOTE_DEVICE_T *this_device, 1610 U32 frame_index 1611 ) 1612 { 1613 SCI_STATUS result; 1614 SCI_SSP_FRAME_HEADER_T *frame_header; 1615 SCIC_SDS_REQUEST_T *io_request; 1616 1617 result = scic_sds_unsolicited_frame_control_get_header( 1618 &(scic_sds_remote_device_get_controller(this_device)->uf_control), 1619 frame_index, 1620 (void **)&frame_header 1621 ); 1622 1623 if (SCI_SUCCESS == result) 1624 { 1625 io_request = scic_sds_controller_get_io_request_from_tag( 1626 scic_sds_remote_device_get_controller(this_device), frame_header->tag); 1627 1628 if ( (io_request == SCI_INVALID_HANDLE) 1629 || (io_request->target_device != this_device) ) 1630 { 1631 // We could not map this tag to a valid IO request 1632 // Just toss the frame and continue 1633 scic_sds_controller_release_frame( 1634 scic_sds_remote_device_get_controller(this_device), frame_index 1635 ); 1636 } 1637 else 1638 { 1639 // The IO request is now in charge of releasing the frame 1640 result = io_request->state_handlers->frame_handler( 1641 io_request, frame_index); 1642 } 1643 } 1644 1645 return result; 1646 } 1647 1648 /** 1649 * This is a common method for handling events reported to the remote device 1650 * from the controller object. 1651 * 1652 * @param [in] this_device This is the device object that is receiving the 1653 * event. 1654 * @param [in] event_code The event code to process. 1655 * 1656 * @return SCI_STATUS 1657 */ 1658 SCI_STATUS scic_sds_remote_device_general_event_handler( 1659 SCIC_SDS_REMOTE_DEVICE_T * this_device, 1660 U32 event_code 1661 ) 1662 { 1663 return scic_sds_remote_device_core_event_handler( this_device, 1664 event_code, 1665 TRUE ); 1666 } 1667 1668 //***************************************************************************** 1669 //* STOPPED STATE HANDLERS 1670 //***************************************************************************** 1671 1672 /** 1673 * This method takes the SCIC_SDS_REMOTE_DEVICE from a stopped state and 1674 * attempts to start it. The RNC buffer for the device is constructed and 1675 * the device state machine is transitioned to the 1676 * SCIC_BASE_REMOTE_DEVICE_STATE_STARTING. 1677 * 1678 * @param[in] device 1679 * 1680 * @return SCI_STATUS 1681 * @retval SCI_SUCCESS if there is an RNC buffer available to construct the 1682 * remote device. 1683 * @retval SCI_FAILURE_INSUFFICIENT_RESOURCES if there is no RNC buffer 1684 * available in which to construct the remote device. 1685 */ 1686 static 1687 SCI_STATUS scic_sds_remote_device_stopped_state_start_handler( 1688 SCI_BASE_REMOTE_DEVICE_T *device 1689 ) 1690 { 1691 SCI_STATUS status; 1692 SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 1693 1694 status = scic_sds_remote_node_context_resume( 1695 this_device->rnc, 1696 scic_sds_remote_device_resume_complete_handler, 1697 this_device 1698 ); 1699 1700 if (status == SCI_SUCCESS) 1701 { 1702 sci_base_state_machine_change_state( 1703 scic_sds_remote_device_get_base_state_machine(this_device), 1704 SCI_BASE_REMOTE_DEVICE_STATE_STARTING 1705 ); 1706 } 1707 1708 return status; 1709 } 1710 1711 /** 1712 * This method will stop a SCIC_SDS_REMOTE_DEVICE that is already in a stopped 1713 * state. This is not considered an error since the device is already 1714 * stopped. 1715 * 1716 * @param[in] this_device The SCI_BASE_REMOTE_DEVICE which is cast into a 1717 * SCIC_SDS_REMOTE_DEVICE. 1718 * 1719 * @return SCI_STATUS 1720 * @retval SCI_SUCCESS 1721 */ 1722 static 1723 SCI_STATUS scic_sds_remote_device_stopped_state_stop_handler( 1724 SCI_BASE_REMOTE_DEVICE_T *this_device 1725 ) 1726 { 1727 return SCI_SUCCESS; 1728 } 1729 1730 /** 1731 * This method will destruct a SCIC_SDS_REMOTE_DEVICE that is in a stopped 1732 * state. This is the only state from which a destruct request will succeed. 1733 * The RNi for this SCIC_SDS_REMOTE_DEVICE is returned to the free pool and 1734 * the device object transitions to the SCI_BASE_REMOTE_DEVICE_STATE_FINAL. 1735 * 1736 * @param[in] this_device The SCI_BASE_REMOTE_DEVICE which is cast into a 1737 * SCIC_SDS_REMOTE_DEVICE. 1738 * 1739 * @return SCI_STATUS 1740 * @retval SCI_SUCCESS 1741 */ 1742 static 1743 SCI_STATUS scic_sds_remote_device_stopped_state_destruct_handler( 1744 SCI_BASE_REMOTE_DEVICE_T *device 1745 ) 1746 { 1747 SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 1748 1749 SCIC_SDS_CONTROLLER_T * the_controller = 1750 scic_sds_remote_device_get_controller(this_device); 1751 1752 the_controller->remote_device_sequence[this_device->rnc->remote_node_index]++; 1753 1754 scic_sds_controller_free_remote_node_context( 1755 the_controller, 1756 this_device, 1757 this_device->rnc->remote_node_index 1758 ); 1759 1760 scic_sds_remote_node_context_set_remote_node_index( 1761 this_device->rnc, 1762 SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX 1763 ); 1764 1765 sci_base_state_machine_change_state( 1766 scic_sds_remote_device_get_base_state_machine(this_device), 1767 SCI_BASE_REMOTE_DEVICE_STATE_FINAL 1768 ); 1769 1770 scic_sds_remote_device_deinitialize_state_logging(this_device); 1771 1772 return SCI_SUCCESS; 1773 } 1774 1775 //***************************************************************************** 1776 //* STARTING STATE HANDLERS 1777 //***************************************************************************** 1778 1779 static 1780 SCI_STATUS scic_sds_remote_device_starting_state_stop_handler( 1781 SCI_BASE_REMOTE_DEVICE_T *device 1782 ) 1783 { 1784 SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 1785 1786 /* 1787 * This device has not yet started so there had better be no IO requests 1788 */ 1789 ASSERT(this_device->started_request_count == 0); 1790 1791 /* 1792 * Destroy the remote node context 1793 */ 1794 scic_sds_remote_node_context_destruct( 1795 this_device->rnc, 1796 scic_sds_cb_remote_device_rnc_destruct_complete, 1797 this_device 1798 ); 1799 1800 /* 1801 * Transition to the stopping state and wait for the remote node to 1802 * complete being posted and invalidated. 1803 */ 1804 sci_base_state_machine_change_state( 1805 scic_sds_remote_device_get_base_state_machine(this_device), 1806 SCI_BASE_REMOTE_DEVICE_STATE_STOPPING 1807 ); 1808 1809 return SCI_SUCCESS; 1810 } 1811 1812 //***************************************************************************** 1813 //* INITIALIZING STATE HANDLERS 1814 //***************************************************************************** 1815 1816 /* There is nothing to do here for SSP devices */ 1817 1818 //***************************************************************************** 1819 //* READY STATE HANDLERS 1820 //***************************************************************************** 1821 1822 /** 1823 * This method is the default stop handler for the SCIC_SDS_REMOTE_DEVICE 1824 * ready substate machine. It will stop the current substate machine and 1825 * transition the base state machine to SCI_BASE_REMOTE_DEVICE_STATE_STOPPING. 1826 * 1827 * @param[in] device The SCI_BASE_REMOTE_DEVICE object which is cast to a 1828 * SCIC_SDS_REMOTE_DEVICE object. 1829 * 1830 * @return SCI_STATUS 1831 * @retval SCI_SUCCESS 1832 */ 1833 SCI_STATUS scic_sds_remote_device_ready_state_stop_handler( 1834 SCI_BASE_REMOTE_DEVICE_T *device 1835 ) 1836 { 1837 SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 1838 SCI_STATUS status = SCI_SUCCESS; 1839 1840 // Request the parent state machine to transition to the stopping state 1841 sci_base_state_machine_change_state( 1842 scic_sds_remote_device_get_base_state_machine(this_device), 1843 SCI_BASE_REMOTE_DEVICE_STATE_STOPPING 1844 ); 1845 1846 if (this_device->started_request_count == 0) 1847 { 1848 scic_sds_remote_node_context_destruct( 1849 this_device->rnc, 1850 scic_sds_cb_remote_device_rnc_destruct_complete, 1851 this_device 1852 ); 1853 } 1854 else 1855 status = scic_sds_remote_device_terminate_requests(this_device); 1856 1857 return status; 1858 } 1859 1860 /** 1861 * This is the ready state device reset handler 1862 * 1863 * @param[in] device The SCI_BASE_REMOTE_DEVICE object which is cast to a 1864 * SCIC_SDS_REMOTE_DEVICE object. 1865 * 1866 * @return SCI_STATUS 1867 */ 1868 SCI_STATUS scic_sds_remote_device_ready_state_reset_handler( 1869 SCI_BASE_REMOTE_DEVICE_T *device 1870 ) 1871 { 1872 SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 1873 1874 // Request the parent state machine to transition to the stopping state 1875 sci_base_state_machine_change_state( 1876 scic_sds_remote_device_get_base_state_machine(this_device), 1877 SCI_BASE_REMOTE_DEVICE_STATE_RESETTING 1878 ); 1879 1880 return SCI_SUCCESS; 1881 } 1882 1883 /** 1884 * This method will attempt to start a task request for this device object. 1885 * The remote device object will issue the start request for the task and if 1886 * successful it will start the request for the port object then increment its 1887 * own requet count. 1888 * 1889 * @param[in] device The SCI_BASE_REMOTE_DEVICE which is cast to a 1890 * SCIC_SDS_REMOTE_DEVICE for which the request is to be started. 1891 * @param[in] request The SCI_BASE_REQUEST which is cast to a 1892 * SCIC_SDS_IO_REQUEST that is to be started. 1893 * 1894 * @return SCI_STATUS 1895 * @retval SCI_SUCCESS if the task request is started for this device object. 1896 * @retval SCI_FAILURE_INSUFFICIENT_RESOURCES if the io request object could 1897 * not get the resources to start. 1898 */ 1899 static 1900 SCI_STATUS scic_sds_remote_device_ready_state_start_task_handler( 1901 SCI_BASE_REMOTE_DEVICE_T *device, 1902 SCI_BASE_REQUEST_T *request 1903 ) 1904 { 1905 SCI_STATUS result; 1906 SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 1907 SCIC_SDS_REQUEST_T *task_request = (SCIC_SDS_REQUEST_T *)request; 1908 1909 // See if the port is in a state where we can start the IO request 1910 result = scic_sds_port_start_io( 1911 scic_sds_remote_device_get_port(this_device), this_device, task_request); 1912 1913 if (result == SCI_SUCCESS) 1914 { 1915 result = scic_sds_remote_node_context_start_task( 1916 this_device->rnc, task_request 1917 ); 1918 1919 if (result == SCI_SUCCESS) 1920 { 1921 result = scic_sds_request_start(task_request); 1922 } 1923 1924 scic_sds_remote_device_start_request(this_device, task_request, result); 1925 } 1926 1927 return result; 1928 } 1929 1930 /** 1931 * This method will attempt to start an io request for this device object. The 1932 * remote device object will issue the start request for the io and if 1933 * successful it will start the request for the port object then increment its 1934 * own requet count. 1935 * 1936 * @param[in] device The SCI_BASE_REMOTE_DEVICE which is cast to a 1937 * SCIC_SDS_REMOTE_DEVICE for which the request is to be started. 1938 * @param[in] request The SCI_BASE_REQUEST which is cast to a 1939 * SCIC_SDS_IO_REQUEST that is to be started. 1940 * 1941 * @return SCI_STATUS 1942 * @retval SCI_SUCCESS if the io request is started for this device object. 1943 * @retval SCI_FAILURE_INSUFFICIENT_RESOURCES if the io request object could 1944 * not get the resources to start. 1945 */ 1946 static 1947 SCI_STATUS scic_sds_remote_device_ready_state_start_io_handler( 1948 SCI_BASE_REMOTE_DEVICE_T *device, 1949 SCI_BASE_REQUEST_T *request 1950 ) 1951 { 1952 SCI_STATUS result; 1953 SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 1954 SCIC_SDS_REQUEST_T *io_request = (SCIC_SDS_REQUEST_T *)request; 1955 1956 // See if the port is in a state where we can start the IO request 1957 result = scic_sds_port_start_io( 1958 scic_sds_remote_device_get_port(this_device), this_device, io_request); 1959 1960 if (result == SCI_SUCCESS) 1961 { 1962 result = scic_sds_remote_node_context_start_io( 1963 this_device->rnc, io_request 1964 ); 1965 1966 if (result == SCI_SUCCESS) 1967 { 1968 result = scic_sds_request_start(io_request); 1969 } 1970 1971 scic_sds_remote_device_start_request(this_device, io_request, result); 1972 } 1973 1974 return result; 1975 } 1976 1977 /** 1978 * This method will complete the request for the remote device object. The 1979 * method will call the completion handler for the request object and if 1980 * successful it will complete the request on the port object then decrement 1981 * its own started_request_count. 1982 * 1983 * @param[in] device The SCI_BASE_REMOTE_DEVICE which is cast to a 1984 * SCIC_SDS_REMOTE_DEVICE for which the request is to be completed. 1985 * @param[in] request The SCI_BASE_REQUEST which is cast to a 1986 * SCIC_SDS_IO_REQUEST that is to be completed. 1987 * 1988 * @return SCI_STATUS 1989 */ 1990 static 1991 SCI_STATUS scic_sds_remote_device_ready_state_complete_request_handler( 1992 SCI_BASE_REMOTE_DEVICE_T *device, 1993 SCI_BASE_REQUEST_T *request 1994 ) 1995 { 1996 SCI_STATUS result; 1997 SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 1998 SCIC_SDS_REQUEST_T *the_request = (SCIC_SDS_REQUEST_T *)request; 1999 2000 result = scic_sds_request_complete(the_request); 2001 2002 if (result == SCI_SUCCESS) 2003 { 2004 // See if the port is in a state where we can start the IO request 2005 result = scic_sds_port_complete_io( 2006 scic_sds_remote_device_get_port(this_device), this_device, the_request); 2007 2008 if (result == SCI_SUCCESS) 2009 { 2010 scic_sds_remote_device_decrement_request_count(this_device); 2011 } 2012 } 2013 2014 return result; 2015 } 2016 2017 //***************************************************************************** 2018 //* STOPPING STATE HANDLERS 2019 //***************************************************************************** 2020 2021 /** 2022 * This method will stop a SCIC_SDS_REMOTE_DEVICE that is already in the 2023 * SCI_BASE_REMOTE_DEVICE_STATE_STOPPING state. This is not considered an 2024 * error since we allow a stop request on a device that is alreay stopping or 2025 * stopped. 2026 * 2027 * @param[in] this_device The SCI_BASE_REMOTE_DEVICE which is cast into a 2028 * SCIC_SDS_REMOTE_DEVICE. 2029 * 2030 * @return SCI_STATUS 2031 * @retval SCI_SUCCESS 2032 */ 2033 static 2034 SCI_STATUS scic_sds_remote_device_stopping_state_stop_handler( 2035 SCI_BASE_REMOTE_DEVICE_T *device 2036 ) 2037 { 2038 // All requests should have been terminated, but if there is an 2039 // attempt to stop a device already in the stopping state, then 2040 // try again to terminate. 2041 return scic_sds_remote_device_terminate_requests( 2042 (SCIC_SDS_REMOTE_DEVICE_T*)device); 2043 } 2044 2045 2046 /** 2047 * This method completes requests for this SCIC_SDS_REMOTE_DEVICE while it is 2048 * in the SCI_BASE_REMOTE_DEVICE_STATE_STOPPING state. This method calls the 2049 * complete method for the request object and if that is successful the port 2050 * object is called to complete the task request. Then the device object 2051 * itself completes the task request. If SCIC_SDS_REMOTE_DEVICE 2052 * started_request_count goes to 0 and the invalidate RNC request has 2053 * completed the device object can transition to the 2054 * SCI_BASE_REMOTE_DEVICE_STATE_STOPPED. 2055 * 2056 * @param[in] device The device object for which the request is completing. 2057 * @param[in] request The task request that is being completed. 2058 * 2059 * @return SCI_STATUS 2060 */ 2061 static 2062 SCI_STATUS scic_sds_remote_device_stopping_state_complete_request_handler( 2063 SCI_BASE_REMOTE_DEVICE_T *device, 2064 SCI_BASE_REQUEST_T *request 2065 ) 2066 { 2067 SCI_STATUS status = SCI_SUCCESS; 2068 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)request; 2069 SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 2070 2071 status = scic_sds_request_complete(this_request); 2072 if (status == SCI_SUCCESS) 2073 { 2074 status = scic_sds_port_complete_io( 2075 scic_sds_remote_device_get_port(this_device), 2076 this_device, 2077 this_request 2078 ); 2079 2080 if (status == SCI_SUCCESS) 2081 { 2082 scic_sds_remote_device_decrement_request_count(this_device); 2083 2084 if (scic_sds_remote_device_get_request_count(this_device) == 0) 2085 { 2086 scic_sds_remote_node_context_destruct( 2087 this_device->rnc, 2088 scic_sds_cb_remote_device_rnc_destruct_complete, 2089 this_device 2090 ); 2091 } 2092 } 2093 } 2094 2095 return status; 2096 } 2097 2098 //***************************************************************************** 2099 //* RESETTING STATE HANDLERS 2100 //***************************************************************************** 2101 2102 /** 2103 * This method will complete the reset operation when the device is in the 2104 * resetting state. 2105 * 2106 * @param[in] device The SCI_BASE_REMOTE_DEVICE which is to be cast into a 2107 * SCIC_SDS_REMOTE_DEVICE object. 2108 * 2109 * @return SCI_STATUS 2110 */ 2111 static 2112 SCI_STATUS scic_sds_remote_device_resetting_state_reset_complete_handler( 2113 SCI_BASE_REMOTE_DEVICE_T * device 2114 ) 2115 { 2116 SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 2117 2118 sci_base_state_machine_change_state( 2119 &this_device->parent.state_machine, 2120 SCI_BASE_REMOTE_DEVICE_STATE_READY 2121 ); 2122 2123 return SCI_SUCCESS; 2124 } 2125 2126 /** 2127 * This method will stop the remote device while in the resetting state. 2128 * 2129 * @param[in] device The SCI_BASE_REMOTE_DEVICE which is to be cast into a 2130 * SCIC_SDS_REMOTE_DEVICE object. 2131 * 2132 * @return SCI_STATUS 2133 */ 2134 static 2135 SCI_STATUS scic_sds_remote_device_resetting_state_stop_handler( 2136 SCI_BASE_REMOTE_DEVICE_T * device 2137 ) 2138 { 2139 SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 2140 2141 sci_base_state_machine_change_state( 2142 &this_device->parent.state_machine, 2143 SCI_BASE_REMOTE_DEVICE_STATE_STOPPING 2144 ); 2145 2146 return SCI_SUCCESS; 2147 } 2148 2149 /** 2150 * This method completes requests for this SCIC_SDS_REMOTE_DEVICE while it is 2151 * in the SCI_BASE_REMOTE_DEVICE_STATE_RESETTING state. This method calls the 2152 * complete method for the request object and if that is successful the port 2153 * object is called to complete the task request. Then the device object 2154 * itself completes the task request. 2155 * 2156 * @param[in] device The device object for which the request is completing. 2157 * @param[in] request The task request that is being completed. 2158 * 2159 * @return SCI_STATUS 2160 */ 2161 static 2162 SCI_STATUS scic_sds_remote_device_resetting_state_complete_request_handler( 2163 SCI_BASE_REMOTE_DEVICE_T *device, 2164 SCI_BASE_REQUEST_T *request 2165 ) 2166 { 2167 SCI_STATUS status = SCI_SUCCESS; 2168 SCIC_SDS_REQUEST_T *this_request = (SCIC_SDS_REQUEST_T *)request; 2169 SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)device; 2170 2171 status = scic_sds_request_complete(this_request); 2172 2173 if (status == SCI_SUCCESS) 2174 { 2175 status = scic_sds_port_complete_io( 2176 scic_sds_remote_device_get_port(this_device), this_device, this_request); 2177 2178 if (status == SCI_SUCCESS) 2179 { 2180 scic_sds_remote_device_decrement_request_count(this_device); 2181 } 2182 } 2183 2184 return status; 2185 } 2186 2187 //***************************************************************************** 2188 //* FAILED STATE HANDLERS 2189 //***************************************************************************** 2190 2191 SCIC_SDS_REMOTE_DEVICE_STATE_HANDLER_T 2192 scic_sds_remote_device_state_handler_table[SCI_BASE_REMOTE_DEVICE_MAX_STATES] = 2193 { 2194 // SCI_BASE_REMOTE_DEVICE_STATE_INITIAL 2195 { 2196 { 2197 scic_sds_remote_device_default_start_handler, 2198 scic_sds_remote_device_default_stop_handler, 2199 scic_sds_remote_device_default_fail_handler, 2200 scic_sds_remote_device_default_destruct_handler, 2201 scic_sds_remote_device_default_reset_handler, 2202 scic_sds_remote_device_default_reset_complete_handler, 2203 scic_sds_remote_device_default_start_request_handler, 2204 scic_sds_remote_device_default_complete_request_handler, 2205 scic_sds_remote_device_default_continue_request_handler, 2206 scic_sds_remote_device_default_start_request_handler, 2207 scic_sds_remote_device_default_complete_request_handler 2208 }, 2209 scic_sds_remote_device_default_suspend_handler, 2210 scic_sds_remote_device_default_resume_handler, 2211 scic_sds_remote_device_default_event_handler, 2212 scic_sds_remote_device_default_frame_handler 2213 }, 2214 // SCI_BASE_REMOTE_DEVICE_STATE_STOPPED 2215 { 2216 { 2217 scic_sds_remote_device_stopped_state_start_handler, 2218 scic_sds_remote_device_stopped_state_stop_handler, 2219 scic_sds_remote_device_default_fail_handler, 2220 scic_sds_remote_device_stopped_state_destruct_handler, 2221 scic_sds_remote_device_default_reset_handler, 2222 scic_sds_remote_device_default_reset_complete_handler, 2223 scic_sds_remote_device_default_start_request_handler, 2224 scic_sds_remote_device_default_complete_request_handler, 2225 scic_sds_remote_device_default_continue_request_handler, 2226 scic_sds_remote_device_default_start_request_handler, 2227 scic_sds_remote_device_default_complete_request_handler 2228 }, 2229 scic_sds_remote_device_default_suspend_handler, 2230 scic_sds_remote_device_default_resume_handler, 2231 scic_sds_remote_device_default_event_handler, 2232 scic_sds_remote_device_default_frame_handler 2233 }, 2234 // SCI_BASE_REMOTE_DEVICE_STATE_STARTING 2235 { 2236 { 2237 scic_sds_remote_device_default_start_handler, 2238 scic_sds_remote_device_starting_state_stop_handler, 2239 scic_sds_remote_device_default_fail_handler, 2240 scic_sds_remote_device_default_destruct_handler, 2241 scic_sds_remote_device_default_reset_handler, 2242 scic_sds_remote_device_default_reset_complete_handler, 2243 scic_sds_remote_device_default_start_request_handler, 2244 scic_sds_remote_device_default_complete_request_handler, 2245 scic_sds_remote_device_default_continue_request_handler, 2246 scic_sds_remote_device_default_start_request_handler, 2247 scic_sds_remote_device_default_complete_request_handler 2248 }, 2249 scic_sds_remote_device_default_suspend_handler, 2250 scic_sds_remote_device_default_resume_handler, 2251 scic_sds_remote_device_general_event_handler, 2252 scic_sds_remote_device_default_frame_handler 2253 }, 2254 // SCI_BASE_REMOTE_DEVICE_STATE_READY 2255 { 2256 { 2257 scic_sds_remote_device_default_start_handler, 2258 scic_sds_remote_device_ready_state_stop_handler, 2259 scic_sds_remote_device_default_fail_handler, 2260 scic_sds_remote_device_default_destruct_handler, 2261 scic_sds_remote_device_ready_state_reset_handler, 2262 scic_sds_remote_device_default_reset_complete_handler, 2263 scic_sds_remote_device_ready_state_start_io_handler, 2264 scic_sds_remote_device_ready_state_complete_request_handler, 2265 scic_sds_remote_device_default_continue_request_handler, 2266 scic_sds_remote_device_ready_state_start_task_handler, 2267 scic_sds_remote_device_ready_state_complete_request_handler 2268 }, 2269 scic_sds_remote_device_general_suspend_handler, 2270 scic_sds_remote_device_general_resume_handler, 2271 scic_sds_remote_device_general_event_handler, 2272 scic_sds_remote_device_general_frame_handler, 2273 }, 2274 // SCI_BASE_REMOTE_DEVICE_STATE_STOPPING 2275 { 2276 { 2277 scic_sds_remote_device_default_start_handler, 2278 scic_sds_remote_device_stopping_state_stop_handler, 2279 scic_sds_remote_device_default_fail_handler, 2280 scic_sds_remote_device_default_destruct_handler, 2281 scic_sds_remote_device_default_reset_handler, 2282 scic_sds_remote_device_default_reset_complete_handler, 2283 scic_sds_remote_device_default_start_request_handler, 2284 scic_sds_remote_device_stopping_state_complete_request_handler, 2285 scic_sds_remote_device_default_continue_request_handler, 2286 scic_sds_remote_device_default_start_request_handler, 2287 scic_sds_remote_device_stopping_state_complete_request_handler 2288 }, 2289 scic_sds_remote_device_default_suspend_handler, 2290 scic_sds_remote_device_default_resume_handler, 2291 scic_sds_remote_device_general_event_handler, 2292 scic_sds_remote_device_general_frame_handler 2293 }, 2294 // SCI_BASE_REMOTE_DEVICE_STATE_FAILED 2295 { 2296 { 2297 scic_sds_remote_device_default_start_handler, 2298 scic_sds_remote_device_default_stop_handler, 2299 scic_sds_remote_device_default_fail_handler, 2300 scic_sds_remote_device_default_destruct_handler, 2301 scic_sds_remote_device_default_reset_handler, 2302 scic_sds_remote_device_default_reset_complete_handler, 2303 scic_sds_remote_device_default_start_request_handler, 2304 scic_sds_remote_device_default_complete_request_handler, 2305 scic_sds_remote_device_default_continue_request_handler, 2306 scic_sds_remote_device_default_start_request_handler, 2307 scic_sds_remote_device_default_complete_request_handler 2308 }, 2309 scic_sds_remote_device_default_suspend_handler, 2310 scic_sds_remote_device_default_resume_handler, 2311 scic_sds_remote_device_default_event_handler, 2312 scic_sds_remote_device_general_frame_handler 2313 }, 2314 // SCI_BASE_REMOTE_DEVICE_STATE_RESETTING 2315 { 2316 { 2317 scic_sds_remote_device_default_start_handler, 2318 scic_sds_remote_device_resetting_state_stop_handler, 2319 scic_sds_remote_device_default_fail_handler, 2320 scic_sds_remote_device_default_destruct_handler, 2321 scic_sds_remote_device_default_reset_handler, 2322 scic_sds_remote_device_resetting_state_reset_complete_handler, 2323 scic_sds_remote_device_default_start_request_handler, 2324 scic_sds_remote_device_resetting_state_complete_request_handler, 2325 scic_sds_remote_device_default_continue_request_handler, 2326 scic_sds_remote_device_default_start_request_handler, 2327 scic_sds_remote_device_resetting_state_complete_request_handler 2328 }, 2329 scic_sds_remote_device_default_suspend_handler, 2330 scic_sds_remote_device_default_resume_handler, 2331 scic_sds_remote_device_default_event_handler, 2332 scic_sds_remote_device_general_frame_handler 2333 }, 2334 #if !defined(DISABLE_WIDE_PORTED_TARGETS) 2335 // SCI_BASE_REMOTE_DEVICE_STATE_UPDATING_PORT_WIDTH - unused by SCIC 2336 { 2337 { 2338 scic_sds_remote_device_default_start_handler, 2339 scic_sds_remote_device_default_stop_handler, 2340 scic_sds_remote_device_default_fail_handler, 2341 scic_sds_remote_device_default_destruct_handler, 2342 scic_sds_remote_device_default_reset_handler, 2343 scic_sds_remote_device_default_reset_complete_handler, 2344 scic_sds_remote_device_default_start_request_handler, 2345 scic_sds_remote_device_default_complete_request_handler, 2346 scic_sds_remote_device_default_continue_request_handler, 2347 scic_sds_remote_device_default_start_request_handler, 2348 scic_sds_remote_device_default_complete_request_handler 2349 }, 2350 scic_sds_remote_device_default_suspend_handler, 2351 scic_sds_remote_device_default_resume_handler, 2352 scic_sds_remote_device_default_event_handler, 2353 scic_sds_remote_device_default_frame_handler 2354 }, 2355 #endif 2356 // SCI_BASE_REMOTE_DEVICE_STATE_FINAL 2357 { 2358 { 2359 scic_sds_remote_device_default_start_handler, 2360 scic_sds_remote_device_default_stop_handler, 2361 scic_sds_remote_device_default_fail_handler, 2362 scic_sds_remote_device_default_destruct_handler, 2363 scic_sds_remote_device_default_reset_handler, 2364 scic_sds_remote_device_default_reset_complete_handler, 2365 scic_sds_remote_device_default_start_request_handler, 2366 scic_sds_remote_device_default_complete_request_handler, 2367 scic_sds_remote_device_default_continue_request_handler, 2368 scic_sds_remote_device_default_start_request_handler, 2369 scic_sds_remote_device_default_complete_request_handler 2370 }, 2371 scic_sds_remote_device_default_suspend_handler, 2372 scic_sds_remote_device_default_resume_handler, 2373 scic_sds_remote_device_default_event_handler, 2374 scic_sds_remote_device_default_frame_handler 2375 } 2376 }; 2377 2378 /** 2379 * This is the enter method for the SCI_BASE_REMOTE_DEVICE_STATE_INITIAL it 2380 * immediately transitions the remote device object to the stopped state. 2381 * 2382 * @param[in] object This is the SCI_BASE_OBJECT that is cast into a 2383 * SCIC_SDS_REMOTE_DEVICE. 2384 * 2385 * @return none 2386 */ 2387 static 2388 void scic_sds_remote_device_initial_state_enter( 2389 SCI_BASE_OBJECT_T *object 2390 ) 2391 { 2392 SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)object; 2393 2394 SET_STATE_HANDLER( 2395 this_device, 2396 scic_sds_remote_device_state_handler_table, 2397 SCI_BASE_REMOTE_DEVICE_STATE_INITIAL 2398 ); 2399 2400 // Initial state is a transitional state to the stopped state 2401 sci_base_state_machine_change_state( 2402 scic_sds_remote_device_get_base_state_machine(this_device), 2403 SCI_BASE_REMOTE_DEVICE_STATE_STOPPED 2404 ); 2405 } 2406 2407 /** 2408 * This is the enter method for the SCI_BASE_REMOTE_DEVICE_STATE_INITIAL it 2409 * sets the stopped state handlers and if this state is entered from the 2410 * SCI_BASE_REMOTE_DEVICE_STATE_STOPPING then the SCI User is informed that 2411 * the device stop is complete. 2412 * 2413 * @param[in] object This is the SCI_BASE_OBJECT that is cast into a 2414 * SCIC_SDS_REMOTE_DEVICE. 2415 * 2416 * @return none 2417 */ 2418 static 2419 void scic_sds_remote_device_stopped_state_enter( 2420 SCI_BASE_OBJECT_T *object 2421 ) 2422 { 2423 SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)object; 2424 2425 SET_STATE_HANDLER( 2426 this_device, 2427 scic_sds_remote_device_state_handler_table, 2428 SCI_BASE_REMOTE_DEVICE_STATE_STOPPED 2429 ); 2430 2431 // If we are entering from the stopping state let the SCI User know that 2432 // the stop operation has completed. 2433 if (this_device->parent.state_machine.previous_state_id 2434 == SCI_BASE_REMOTE_DEVICE_STATE_STOPPING) 2435 { 2436 scic_cb_remote_device_stop_complete( 2437 scic_sds_remote_device_get_controller(this_device), 2438 this_device, 2439 SCI_SUCCESS 2440 ); 2441 } 2442 2443 scic_sds_controller_remote_device_stopped( 2444 scic_sds_remote_device_get_controller(this_device), 2445 this_device 2446 ); 2447 } 2448 2449 /** 2450 * This is the enter method for the SCI_BASE_REMOTE_DEVICE_STATE_STARTING it 2451 * sets the starting state handlers, sets the device not ready, and posts the 2452 * remote node context to the hardware. 2453 * 2454 * @param[in] object This is the SCI_BASE_OBJECT that is cast into a 2455 * SCIC_SDS_REMOTE_DEVICE. 2456 * 2457 * @return none 2458 */ 2459 static 2460 void scic_sds_remote_device_starting_state_enter( 2461 SCI_BASE_OBJECT_T *object 2462 ) 2463 { 2464 SCIC_SDS_CONTROLLER_T * the_controller; 2465 SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)object; 2466 2467 the_controller = scic_sds_remote_device_get_controller(this_device); 2468 2469 SET_STATE_HANDLER( 2470 this_device, 2471 scic_sds_remote_device_state_handler_table, 2472 SCI_BASE_REMOTE_DEVICE_STATE_STARTING 2473 ); 2474 2475 scic_cb_remote_device_not_ready( 2476 the_controller, 2477 this_device, 2478 SCIC_REMOTE_DEVICE_NOT_READY_START_REQUESTED 2479 ); 2480 } 2481 2482 2483 /** 2484 * This is the enter method for the SCI_BASE_REMOTE_DEVICE_STATE_READY it sets 2485 * the ready state handlers, and starts the ready substate machine. 2486 * 2487 * @param[in] object This is the SCI_BASE_OBJECT that is cast into a 2488 * SCIC_SDS_REMOTE_DEVICE. 2489 * 2490 * @return none 2491 */ 2492 static 2493 void scic_sds_remote_device_ready_state_enter( 2494 SCI_BASE_OBJECT_T *object 2495 ) 2496 { 2497 SCIC_SDS_CONTROLLER_T * the_controller; 2498 SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)object; 2499 2500 the_controller = scic_sds_remote_device_get_controller(this_device); 2501 2502 SET_STATE_HANDLER( 2503 this_device, 2504 scic_sds_remote_device_state_handler_table, 2505 SCI_BASE_REMOTE_DEVICE_STATE_READY 2506 ); 2507 2508 /// @todo Check the device object for the proper return code for this 2509 /// callback 2510 scic_cb_remote_device_start_complete( 2511 the_controller, this_device, SCI_SUCCESS 2512 ); 2513 2514 scic_sds_controller_remote_device_started( 2515 the_controller, this_device 2516 ); 2517 2518 if (this_device->has_ready_substate_machine) 2519 { 2520 sci_base_state_machine_start(&this_device->ready_substate_machine); 2521 } 2522 else 2523 { 2524 scic_cb_remote_device_ready(the_controller, this_device); 2525 } 2526 } 2527 2528 /** 2529 * This is the exit method for the SCI_BASE_REMOTE_DEVICE_STATE_READY it does 2530 * nothing. 2531 * 2532 * @param[in] object This is the SCI_BASE_OBJECT that is cast into a 2533 * SCIC_SDS_REMOTE_DEVICE. 2534 * 2535 * @return none 2536 */ 2537 static 2538 void scic_sds_remote_device_ready_state_exit( 2539 SCI_BASE_OBJECT_T *object 2540 ) 2541 { 2542 SCIC_SDS_CONTROLLER_T * the_controller; 2543 SCIC_SDS_REMOTE_DEVICE_T * this_device = (SCIC_SDS_REMOTE_DEVICE_T *)object; 2544 2545 the_controller = scic_sds_remote_device_get_controller(this_device); 2546 2547 if (this_device->has_ready_substate_machine) 2548 { 2549 sci_base_state_machine_stop(&this_device->ready_substate_machine); 2550 } 2551 else 2552 { 2553 scic_cb_remote_device_not_ready( 2554 the_controller, 2555 this_device, 2556 SCIC_REMOTE_DEVICE_NOT_READY_STOP_REQUESTED 2557 ); 2558 } 2559 } 2560 2561 /** 2562 * This is the enter method for the SCI_BASE_REMOTE_DEVICE_STATE_STOPPING it 2563 * sets the stopping state handlers and posts an RNC invalidate request to the 2564 * SCU hardware. 2565 * 2566 * @param[in] object This is the SCI_BASE_OBJECT that is cast into a 2567 * SCIC_SDS_REMOTE_DEVICE. 2568 * 2569 * @return none 2570 */ 2571 static 2572 void scic_sds_remote_device_stopping_state_enter( 2573 SCI_BASE_OBJECT_T *object 2574 ) 2575 { 2576 SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)object; 2577 2578 SET_STATE_HANDLER( 2579 this_device, 2580 scic_sds_remote_device_state_handler_table, 2581 SCI_BASE_REMOTE_DEVICE_STATE_STOPPING 2582 ); 2583 } 2584 2585 /** 2586 * This is the enter method for the SCI_BASE_REMOTE_DEVICE_STATE_FAILED it 2587 * sets the stopping state handlers. 2588 * 2589 * @param[in] object This is the SCI_BASE_OBJECT that is cast into a 2590 * SCIC_SDS_REMOTE_DEVICE. 2591 * 2592 * @return none 2593 */ 2594 static 2595 void scic_sds_remote_device_failed_state_enter( 2596 SCI_BASE_OBJECT_T *object 2597 ) 2598 { 2599 SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)object; 2600 2601 SET_STATE_HANDLER( 2602 this_device, 2603 scic_sds_remote_device_state_handler_table, 2604 SCI_BASE_REMOTE_DEVICE_STATE_FAILED 2605 ); 2606 } 2607 2608 /** 2609 * This is the enter method for the SCI_BASE_REMOTE_DEVICE_STATE_RESETTING it 2610 * sets the resetting state handlers. 2611 * 2612 * @param[in] object This is the SCI_BASE_OBJECT that is cast into a 2613 * SCIC_SDS_REMOTE_DEVICE. 2614 * 2615 * @return none 2616 */ 2617 static 2618 void scic_sds_remote_device_resetting_state_enter( 2619 SCI_BASE_OBJECT_T *object 2620 ) 2621 { 2622 SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)object; 2623 2624 SET_STATE_HANDLER( 2625 this_device, 2626 scic_sds_remote_device_state_handler_table, 2627 SCI_BASE_REMOTE_DEVICE_STATE_RESETTING 2628 ); 2629 2630 scic_sds_remote_node_context_suspend( 2631 this_device->rnc, SCI_SOFTWARE_SUSPENSION, NULL, NULL); 2632 } 2633 2634 /** 2635 * This is the exit method for the SCI_BASE_REMOTE_DEVICE_STATE_RESETTING it 2636 * does nothing. 2637 * 2638 * @param[in] object This is the SCI_BASE_OBJECT that is cast into a 2639 * SCIC_SDS_REMOTE_DEVICE. 2640 * 2641 * @return none 2642 */ 2643 static 2644 void scic_sds_remote_device_resetting_state_exit( 2645 SCI_BASE_OBJECT_T *object 2646 ) 2647 { 2648 SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)object; 2649 2650 scic_sds_remote_node_context_resume(this_device->rnc, NULL, NULL); 2651 } 2652 2653 /** 2654 * This is the enter method for the SCI_BASE_REMOTE_DEVICE_STATE_FINAL it sets 2655 * the final state handlers. 2656 * 2657 * @param[in] object This is the SCI_BASE_OBJECT that is cast into a 2658 * SCIC_SDS_REMOTE_DEVICE. 2659 * 2660 * @return none 2661 */ 2662 static 2663 void scic_sds_remote_device_final_state_enter( 2664 SCI_BASE_OBJECT_T *object 2665 ) 2666 { 2667 SCIC_SDS_REMOTE_DEVICE_T *this_device = (SCIC_SDS_REMOTE_DEVICE_T *)object; 2668 2669 SET_STATE_HANDLER( 2670 this_device, 2671 scic_sds_remote_device_state_handler_table, 2672 SCI_BASE_REMOTE_DEVICE_STATE_FINAL 2673 ); 2674 } 2675 2676 // --------------------------------------------------------------------------- 2677 2678 SCI_BASE_STATE_T 2679 scic_sds_remote_device_state_table[SCI_BASE_REMOTE_DEVICE_MAX_STATES] = 2680 { 2681 { 2682 SCI_BASE_REMOTE_DEVICE_STATE_INITIAL, 2683 scic_sds_remote_device_initial_state_enter, 2684 NULL 2685 }, 2686 { 2687 SCI_BASE_REMOTE_DEVICE_STATE_STOPPED, 2688 scic_sds_remote_device_stopped_state_enter, 2689 NULL 2690 }, 2691 { 2692 SCI_BASE_REMOTE_DEVICE_STATE_STARTING, 2693 scic_sds_remote_device_starting_state_enter, 2694 NULL 2695 }, 2696 { 2697 SCI_BASE_REMOTE_DEVICE_STATE_READY, 2698 scic_sds_remote_device_ready_state_enter, 2699 scic_sds_remote_device_ready_state_exit 2700 }, 2701 { 2702 SCI_BASE_REMOTE_DEVICE_STATE_STOPPING, 2703 scic_sds_remote_device_stopping_state_enter, 2704 NULL 2705 }, 2706 { 2707 SCI_BASE_REMOTE_DEVICE_STATE_FAILED, 2708 scic_sds_remote_device_failed_state_enter, 2709 NULL 2710 }, 2711 { 2712 SCI_BASE_REMOTE_DEVICE_STATE_RESETTING, 2713 scic_sds_remote_device_resetting_state_enter, 2714 scic_sds_remote_device_resetting_state_exit 2715 }, 2716 #if !defined(DISABLE_WIDE_PORTED_TARGETS) 2717 { //Not used by SCIC 2718 SCI_BASE_REMOTE_DEVICE_STATE_UPDATING_PORT_WIDTH, 2719 NULL, 2720 NULL 2721 }, 2722 #endif //#if !defined(DISABLE_WIDE_PORTED_TARGETS) 2723 { 2724 SCI_BASE_REMOTE_DEVICE_STATE_FINAL, 2725 scic_sds_remote_device_final_state_enter, 2726 NULL 2727 } 2728 }; 2729 2730