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 * * Neither the name of Intel Corporation nor the names of its 40 * contributors may be used to endorse or promote products derived 41 * from this software without specific prior written permission. 42 * 43 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 44 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 45 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 46 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 47 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 48 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 49 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 50 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 51 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 52 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 53 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 54 */ 55 #include <scsi/sas_ata.h> 56 #include "host.h" 57 #include "isci.h" 58 #include "remote_device.h" 59 #include "remote_node_context.h" 60 #include "scu_event_codes.h" 61 #include "scu_task_context.h" 62 63 #undef C 64 #define C(a) (#a) 65 const char *rnc_state_name(enum scis_sds_remote_node_context_states state) 66 { 67 static const char * const strings[] = RNC_STATES; 68 69 if (state >= ARRAY_SIZE(strings)) 70 return "UNKNOWN"; 71 72 return strings[state]; 73 } 74 #undef C 75 76 /** 77 * 78 * @sci_rnc: The state of the remote node context object to check. 79 * 80 * This method will return true if the remote node context is in a READY state 81 * otherwise it will return false bool true if the remote node context is in 82 * the ready state. false if the remote node context is not in the ready state. 83 */ 84 bool sci_remote_node_context_is_ready( 85 struct sci_remote_node_context *sci_rnc) 86 { 87 u32 current_state = sci_rnc->sm.current_state_id; 88 89 if (current_state == SCI_RNC_READY) { 90 return true; 91 } 92 93 return false; 94 } 95 96 bool sci_remote_node_context_is_suspended(struct sci_remote_node_context *sci_rnc) 97 { 98 u32 current_state = sci_rnc->sm.current_state_id; 99 100 if (current_state == SCI_RNC_TX_RX_SUSPENDED) 101 return true; 102 return false; 103 } 104 105 static union scu_remote_node_context *sci_rnc_by_id(struct isci_host *ihost, u16 id) 106 { 107 if (id < ihost->remote_node_entries && 108 ihost->device_table[id]) 109 return &ihost->remote_node_context_table[id]; 110 111 return NULL; 112 } 113 114 static void sci_remote_node_context_construct_buffer(struct sci_remote_node_context *sci_rnc) 115 { 116 struct isci_remote_device *idev = rnc_to_dev(sci_rnc); 117 struct domain_device *dev = idev->domain_dev; 118 int rni = sci_rnc->remote_node_index; 119 union scu_remote_node_context *rnc; 120 struct isci_host *ihost; 121 __le64 sas_addr; 122 123 ihost = idev->owning_port->owning_controller; 124 rnc = sci_rnc_by_id(ihost, rni); 125 126 memset(rnc, 0, sizeof(union scu_remote_node_context) 127 * sci_remote_device_node_count(idev)); 128 129 rnc->ssp.remote_node_index = rni; 130 rnc->ssp.remote_node_port_width = idev->device_port_width; 131 rnc->ssp.logical_port_index = idev->owning_port->physical_port_index; 132 133 /* sas address is __be64, context ram format is __le64 */ 134 sas_addr = cpu_to_le64(SAS_ADDR(dev->sas_addr)); 135 rnc->ssp.remote_sas_address_hi = upper_32_bits(sas_addr); 136 rnc->ssp.remote_sas_address_lo = lower_32_bits(sas_addr); 137 138 rnc->ssp.nexus_loss_timer_enable = true; 139 rnc->ssp.check_bit = false; 140 rnc->ssp.is_valid = false; 141 rnc->ssp.is_remote_node_context = true; 142 rnc->ssp.function_number = 0; 143 144 rnc->ssp.arbitration_wait_time = 0; 145 146 if (dev_is_sata(dev)) { 147 rnc->ssp.connection_occupancy_timeout = 148 ihost->user_parameters.stp_max_occupancy_timeout; 149 rnc->ssp.connection_inactivity_timeout = 150 ihost->user_parameters.stp_inactivity_timeout; 151 } else { 152 rnc->ssp.connection_occupancy_timeout = 153 ihost->user_parameters.ssp_max_occupancy_timeout; 154 rnc->ssp.connection_inactivity_timeout = 155 ihost->user_parameters.ssp_inactivity_timeout; 156 } 157 158 rnc->ssp.initial_arbitration_wait_time = 0; 159 160 /* Open Address Frame Parameters */ 161 rnc->ssp.oaf_connection_rate = idev->connection_rate; 162 rnc->ssp.oaf_features = 0; 163 rnc->ssp.oaf_source_zone_group = 0; 164 rnc->ssp.oaf_more_compatibility_features = 0; 165 } 166 /** 167 * 168 * @sci_rnc: 169 * @callback: 170 * @callback_parameter: 171 * 172 * This method will setup the remote node context object so it will transition 173 * to its ready state. If the remote node context is already setup to 174 * transition to its final state then this function does nothing. none 175 */ 176 static void sci_remote_node_context_setup_to_resume( 177 struct sci_remote_node_context *sci_rnc, 178 scics_sds_remote_node_context_callback callback, 179 void *callback_parameter, 180 enum sci_remote_node_context_destination_state dest_param) 181 { 182 if (sci_rnc->destination_state != RNC_DEST_FINAL) { 183 sci_rnc->destination_state = dest_param; 184 if (callback != NULL) { 185 sci_rnc->user_callback = callback; 186 sci_rnc->user_cookie = callback_parameter; 187 } 188 } 189 } 190 191 static void sci_remote_node_context_setup_to_destroy( 192 struct sci_remote_node_context *sci_rnc, 193 scics_sds_remote_node_context_callback callback, 194 void *callback_parameter) 195 { 196 struct isci_host *ihost = idev_to_ihost(rnc_to_dev(sci_rnc)); 197 198 sci_rnc->destination_state = RNC_DEST_FINAL; 199 sci_rnc->user_callback = callback; 200 sci_rnc->user_cookie = callback_parameter; 201 202 wake_up(&ihost->eventq); 203 } 204 205 /** 206 * 207 * 208 * This method just calls the user callback function and then resets the 209 * callback. 210 */ 211 static void sci_remote_node_context_notify_user( 212 struct sci_remote_node_context *rnc) 213 { 214 if (rnc->user_callback != NULL) { 215 (*rnc->user_callback)(rnc->user_cookie); 216 217 rnc->user_callback = NULL; 218 rnc->user_cookie = NULL; 219 } 220 } 221 222 static void sci_remote_node_context_continue_state_transitions(struct sci_remote_node_context *rnc) 223 { 224 switch (rnc->destination_state) { 225 case RNC_DEST_READY: 226 case RNC_DEST_SUSPENDED_RESUME: 227 rnc->destination_state = RNC_DEST_READY; 228 /* Fall through... */ 229 case RNC_DEST_FINAL: 230 sci_remote_node_context_resume(rnc, rnc->user_callback, 231 rnc->user_cookie); 232 break; 233 default: 234 rnc->destination_state = RNC_DEST_UNSPECIFIED; 235 break; 236 } 237 } 238 239 static void sci_remote_node_context_validate_context_buffer(struct sci_remote_node_context *sci_rnc) 240 { 241 union scu_remote_node_context *rnc_buffer; 242 struct isci_remote_device *idev = rnc_to_dev(sci_rnc); 243 struct domain_device *dev = idev->domain_dev; 244 struct isci_host *ihost = idev->owning_port->owning_controller; 245 246 rnc_buffer = sci_rnc_by_id(ihost, sci_rnc->remote_node_index); 247 248 rnc_buffer->ssp.is_valid = true; 249 250 if (dev_is_sata(dev) && dev->parent) { 251 sci_remote_device_post_request(idev, SCU_CONTEXT_COMMAND_POST_RNC_96); 252 } else { 253 sci_remote_device_post_request(idev, SCU_CONTEXT_COMMAND_POST_RNC_32); 254 255 if (!dev->parent) 256 sci_port_setup_transports(idev->owning_port, 257 sci_rnc->remote_node_index); 258 } 259 } 260 261 static void sci_remote_node_context_invalidate_context_buffer(struct sci_remote_node_context *sci_rnc) 262 { 263 union scu_remote_node_context *rnc_buffer; 264 struct isci_remote_device *idev = rnc_to_dev(sci_rnc); 265 struct isci_host *ihost = idev->owning_port->owning_controller; 266 267 rnc_buffer = sci_rnc_by_id(ihost, sci_rnc->remote_node_index); 268 269 rnc_buffer->ssp.is_valid = false; 270 271 sci_remote_device_post_request(rnc_to_dev(sci_rnc), 272 SCU_CONTEXT_COMMAND_POST_RNC_INVALIDATE); 273 } 274 275 static void sci_remote_node_context_initial_state_enter(struct sci_base_state_machine *sm) 276 { 277 struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm); 278 struct isci_remote_device *idev = rnc_to_dev(rnc); 279 struct isci_host *ihost = idev->owning_port->owning_controller; 280 281 /* Check to see if we have gotten back to the initial state because 282 * someone requested to destroy the remote node context object. 283 */ 284 if (sm->previous_state_id == SCI_RNC_INVALIDATING) { 285 rnc->destination_state = RNC_DEST_UNSPECIFIED; 286 sci_remote_node_context_notify_user(rnc); 287 288 smp_wmb(); 289 wake_up(&ihost->eventq); 290 } 291 } 292 293 static void sci_remote_node_context_posting_state_enter(struct sci_base_state_machine *sm) 294 { 295 struct sci_remote_node_context *sci_rnc = container_of(sm, typeof(*sci_rnc), sm); 296 297 sci_remote_node_context_validate_context_buffer(sci_rnc); 298 } 299 300 static void sci_remote_node_context_invalidating_state_enter(struct sci_base_state_machine *sm) 301 { 302 struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm); 303 304 /* Terminate all outstanding requests. */ 305 sci_remote_device_terminate_requests(rnc_to_dev(rnc)); 306 sci_remote_node_context_invalidate_context_buffer(rnc); 307 } 308 309 static void sci_remote_node_context_resuming_state_enter(struct sci_base_state_machine *sm) 310 { 311 struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm); 312 struct isci_remote_device *idev; 313 struct domain_device *dev; 314 315 idev = rnc_to_dev(rnc); 316 dev = idev->domain_dev; 317 318 /* 319 * For direct attached SATA devices we need to clear the TLCR 320 * NCQ to TCi tag mapping on the phy and in cases where we 321 * resume because of a target reset we also need to update 322 * the STPTLDARNI register with the RNi of the device 323 */ 324 if (dev_is_sata(dev) && !dev->parent) 325 sci_port_setup_transports(idev->owning_port, rnc->remote_node_index); 326 327 sci_remote_device_post_request(idev, SCU_CONTEXT_COMMAND_POST_RNC_RESUME); 328 } 329 330 static void sci_remote_node_context_ready_state_enter(struct sci_base_state_machine *sm) 331 { 332 struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm); 333 enum sci_remote_node_context_destination_state dest_select; 334 int tell_user = 1; 335 336 dest_select = rnc->destination_state; 337 rnc->destination_state = RNC_DEST_UNSPECIFIED; 338 339 if ((dest_select == RNC_DEST_SUSPENDED) || 340 (dest_select == RNC_DEST_SUSPENDED_RESUME)) { 341 sci_remote_node_context_suspend( 342 rnc, rnc->suspend_reason, 343 SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT); 344 345 if (dest_select == RNC_DEST_SUSPENDED_RESUME) 346 tell_user = 0; /* Wait until ready again. */ 347 } 348 if (tell_user) 349 sci_remote_node_context_notify_user(rnc); 350 } 351 352 static void sci_remote_node_context_tx_suspended_state_enter(struct sci_base_state_machine *sm) 353 { 354 struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm); 355 356 sci_remote_node_context_continue_state_transitions(rnc); 357 } 358 359 static void sci_remote_node_context_tx_rx_suspended_state_enter(struct sci_base_state_machine *sm) 360 { 361 struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm); 362 struct isci_remote_device *idev = rnc_to_dev(rnc); 363 struct isci_host *ihost = idev->owning_port->owning_controller; 364 u32 new_count = rnc->suspend_count + 1; 365 366 if (new_count == 0) 367 rnc->suspend_count = 1; 368 else 369 rnc->suspend_count = new_count; 370 smp_wmb(); 371 372 /* Terminate outstanding requests pending abort. */ 373 sci_remote_device_abort_requests_pending_abort(idev); 374 375 wake_up(&ihost->eventq); 376 sci_remote_node_context_continue_state_transitions(rnc); 377 } 378 379 static void sci_remote_node_context_await_suspend_state_exit( 380 struct sci_base_state_machine *sm) 381 { 382 struct sci_remote_node_context *rnc 383 = container_of(sm, typeof(*rnc), sm); 384 struct isci_remote_device *idev = rnc_to_dev(rnc); 385 386 if (dev_is_sata(idev->domain_dev)) 387 isci_dev_set_hang_detection_timeout(idev, 0); 388 } 389 390 static const struct sci_base_state sci_remote_node_context_state_table[] = { 391 [SCI_RNC_INITIAL] = { 392 .enter_state = sci_remote_node_context_initial_state_enter, 393 }, 394 [SCI_RNC_POSTING] = { 395 .enter_state = sci_remote_node_context_posting_state_enter, 396 }, 397 [SCI_RNC_INVALIDATING] = { 398 .enter_state = sci_remote_node_context_invalidating_state_enter, 399 }, 400 [SCI_RNC_RESUMING] = { 401 .enter_state = sci_remote_node_context_resuming_state_enter, 402 }, 403 [SCI_RNC_READY] = { 404 .enter_state = sci_remote_node_context_ready_state_enter, 405 }, 406 [SCI_RNC_TX_SUSPENDED] = { 407 .enter_state = sci_remote_node_context_tx_suspended_state_enter, 408 }, 409 [SCI_RNC_TX_RX_SUSPENDED] = { 410 .enter_state = sci_remote_node_context_tx_rx_suspended_state_enter, 411 }, 412 [SCI_RNC_AWAIT_SUSPENSION] = { 413 .exit_state = sci_remote_node_context_await_suspend_state_exit, 414 }, 415 }; 416 417 void sci_remote_node_context_construct(struct sci_remote_node_context *rnc, 418 u16 remote_node_index) 419 { 420 memset(rnc, 0, sizeof(struct sci_remote_node_context)); 421 422 rnc->remote_node_index = remote_node_index; 423 rnc->destination_state = RNC_DEST_UNSPECIFIED; 424 425 sci_init_sm(&rnc->sm, sci_remote_node_context_state_table, SCI_RNC_INITIAL); 426 } 427 428 enum sci_status sci_remote_node_context_event_handler(struct sci_remote_node_context *sci_rnc, 429 u32 event_code) 430 { 431 enum scis_sds_remote_node_context_states state; 432 u32 next_state; 433 434 state = sci_rnc->sm.current_state_id; 435 switch (state) { 436 case SCI_RNC_POSTING: 437 switch (scu_get_event_code(event_code)) { 438 case SCU_EVENT_POST_RNC_COMPLETE: 439 sci_change_state(&sci_rnc->sm, SCI_RNC_READY); 440 break; 441 default: 442 goto out; 443 } 444 break; 445 case SCI_RNC_INVALIDATING: 446 if (scu_get_event_code(event_code) == SCU_EVENT_POST_RNC_INVALIDATE_COMPLETE) { 447 if (sci_rnc->destination_state == RNC_DEST_FINAL) 448 next_state = SCI_RNC_INITIAL; 449 else 450 next_state = SCI_RNC_POSTING; 451 sci_change_state(&sci_rnc->sm, next_state); 452 } else { 453 switch (scu_get_event_type(event_code)) { 454 case SCU_EVENT_TYPE_RNC_SUSPEND_TX: 455 case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX: 456 /* We really dont care if the hardware is going to suspend 457 * the device since it's being invalidated anyway */ 458 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), 459 "%s: SCIC Remote Node Context 0x%p was " 460 "suspended by hardware while being " 461 "invalidated.\n", __func__, sci_rnc); 462 break; 463 default: 464 goto out; 465 } 466 } 467 break; 468 case SCI_RNC_RESUMING: 469 if (scu_get_event_code(event_code) == SCU_EVENT_POST_RCN_RELEASE) { 470 sci_change_state(&sci_rnc->sm, SCI_RNC_READY); 471 } else { 472 switch (scu_get_event_type(event_code)) { 473 case SCU_EVENT_TYPE_RNC_SUSPEND_TX: 474 case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX: 475 /* We really dont care if the hardware is going to suspend 476 * the device since it's being resumed anyway */ 477 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), 478 "%s: SCIC Remote Node Context 0x%p was " 479 "suspended by hardware while being resumed.\n", 480 __func__, sci_rnc); 481 break; 482 default: 483 goto out; 484 } 485 } 486 break; 487 case SCI_RNC_READY: 488 switch (scu_get_event_type(event_code)) { 489 case SCU_EVENT_TL_RNC_SUSPEND_TX: 490 sci_change_state(&sci_rnc->sm, SCI_RNC_TX_SUSPENDED); 491 sci_rnc->suspend_type = scu_get_event_type(event_code); 492 break; 493 case SCU_EVENT_TL_RNC_SUSPEND_TX_RX: 494 sci_change_state(&sci_rnc->sm, SCI_RNC_TX_RX_SUSPENDED); 495 sci_rnc->suspend_type = scu_get_event_type(event_code); 496 break; 497 default: 498 goto out; 499 } 500 break; 501 case SCI_RNC_AWAIT_SUSPENSION: 502 switch (scu_get_event_type(event_code)) { 503 case SCU_EVENT_TL_RNC_SUSPEND_TX: 504 next_state = SCI_RNC_TX_SUSPENDED; 505 break; 506 case SCU_EVENT_TL_RNC_SUSPEND_TX_RX: 507 next_state = SCI_RNC_TX_RX_SUSPENDED; 508 break; 509 default: 510 goto out; 511 } 512 if (sci_rnc->suspend_type == scu_get_event_type(event_code)) 513 sci_change_state(&sci_rnc->sm, next_state); 514 break; 515 default: 516 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), 517 "%s: invalid state: %s\n", __func__, 518 rnc_state_name(state)); 519 return SCI_FAILURE_INVALID_STATE; 520 } 521 return SCI_SUCCESS; 522 523 out: 524 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), 525 "%s: code: %#x state: %s\n", __func__, event_code, 526 rnc_state_name(state)); 527 return SCI_FAILURE; 528 529 } 530 531 enum sci_status sci_remote_node_context_destruct(struct sci_remote_node_context *sci_rnc, 532 scics_sds_remote_node_context_callback cb_fn, 533 void *cb_p) 534 { 535 enum scis_sds_remote_node_context_states state; 536 537 state = sci_rnc->sm.current_state_id; 538 switch (state) { 539 case SCI_RNC_INVALIDATING: 540 sci_remote_node_context_setup_to_destroy(sci_rnc, cb_fn, cb_p); 541 return SCI_SUCCESS; 542 case SCI_RNC_POSTING: 543 case SCI_RNC_RESUMING: 544 case SCI_RNC_READY: 545 case SCI_RNC_TX_SUSPENDED: 546 case SCI_RNC_TX_RX_SUSPENDED: 547 sci_remote_node_context_setup_to_destroy(sci_rnc, cb_fn, cb_p); 548 sci_change_state(&sci_rnc->sm, SCI_RNC_INVALIDATING); 549 return SCI_SUCCESS; 550 case SCI_RNC_AWAIT_SUSPENSION: 551 sci_remote_node_context_setup_to_destroy(sci_rnc, cb_fn, cb_p); 552 return SCI_SUCCESS; 553 case SCI_RNC_INITIAL: 554 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), 555 "%s: invalid state: %s\n", __func__, 556 rnc_state_name(state)); 557 /* We have decided that the destruct request on the remote node context 558 * can not fail since it is either in the initial/destroyed state or is 559 * can be destroyed. 560 */ 561 return SCI_SUCCESS; 562 default: 563 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), 564 "%s: invalid state %s\n", __func__, 565 rnc_state_name(state)); 566 return SCI_FAILURE_INVALID_STATE; 567 } 568 } 569 570 enum sci_status sci_remote_node_context_suspend( 571 struct sci_remote_node_context *sci_rnc, 572 enum sci_remote_node_suspension_reasons suspend_reason, 573 u32 suspend_type) 574 { 575 enum scis_sds_remote_node_context_states state 576 = sci_rnc->sm.current_state_id; 577 struct isci_remote_device *idev = rnc_to_dev(sci_rnc); 578 enum sci_status status = SCI_FAILURE_INVALID_STATE; 579 enum sci_remote_node_context_destination_state dest_param = 580 RNC_DEST_UNSPECIFIED; 581 582 dev_dbg(scirdev_to_dev(idev), 583 "%s: current state %s, current suspend_type %x dest state %d," 584 " arg suspend_reason %d, arg suspend_type %x", 585 __func__, rnc_state_name(state), sci_rnc->suspend_type, 586 sci_rnc->destination_state, suspend_reason, 587 suspend_type); 588 589 /* Disable automatic state continuations if explicitly suspending. */ 590 if ((suspend_reason == SCI_HW_SUSPEND) || 591 (sci_rnc->destination_state == RNC_DEST_FINAL)) 592 dest_param = sci_rnc->destination_state; 593 594 switch (state) { 595 case SCI_RNC_READY: 596 break; 597 case SCI_RNC_INVALIDATING: 598 if (sci_rnc->destination_state == RNC_DEST_FINAL) { 599 dev_warn(scirdev_to_dev(idev), 600 "%s: already destroying %p\n", 601 __func__, sci_rnc); 602 return SCI_FAILURE_INVALID_STATE; 603 } 604 /* Fall through and handle like SCI_RNC_POSTING */ 605 case SCI_RNC_RESUMING: 606 /* Fall through and handle like SCI_RNC_POSTING */ 607 case SCI_RNC_POSTING: 608 /* Set the destination state to AWAIT - this signals the 609 * entry into the SCI_RNC_READY state that a suspension 610 * needs to be done immediately. 611 */ 612 if (sci_rnc->destination_state != RNC_DEST_FINAL) 613 sci_rnc->destination_state = RNC_DEST_SUSPENDED; 614 sci_rnc->suspend_type = suspend_type; 615 sci_rnc->suspend_reason = suspend_reason; 616 return SCI_SUCCESS; 617 618 case SCI_RNC_TX_SUSPENDED: 619 if (suspend_type == SCU_EVENT_TL_RNC_SUSPEND_TX) 620 status = SCI_SUCCESS; 621 break; 622 case SCI_RNC_TX_RX_SUSPENDED: 623 if (suspend_type == SCU_EVENT_TL_RNC_SUSPEND_TX_RX) 624 status = SCI_SUCCESS; 625 break; 626 case SCI_RNC_AWAIT_SUSPENSION: 627 if ((sci_rnc->suspend_type == SCU_EVENT_TL_RNC_SUSPEND_TX_RX) 628 || (suspend_type == sci_rnc->suspend_type)) 629 return SCI_SUCCESS; 630 break; 631 default: 632 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), 633 "%s: invalid state %s\n", __func__, 634 rnc_state_name(state)); 635 return SCI_FAILURE_INVALID_STATE; 636 } 637 sci_rnc->destination_state = dest_param; 638 sci_rnc->suspend_type = suspend_type; 639 sci_rnc->suspend_reason = suspend_reason; 640 641 if (status == SCI_SUCCESS) { /* Already in the destination state? */ 642 struct isci_host *ihost = idev->owning_port->owning_controller; 643 644 wake_up_all(&ihost->eventq); /* Let observers look. */ 645 return SCI_SUCCESS; 646 } 647 if ((suspend_reason == SCI_SW_SUSPEND_NORMAL) || 648 (suspend_reason == SCI_SW_SUSPEND_LINKHANG_DETECT)) { 649 650 if (suspend_reason == SCI_SW_SUSPEND_LINKHANG_DETECT) 651 isci_dev_set_hang_detection_timeout(idev, 0x00000001); 652 653 sci_remote_device_post_request( 654 idev, SCI_SOFTWARE_SUSPEND_CMD); 655 } 656 if (state != SCI_RNC_AWAIT_SUSPENSION) 657 sci_change_state(&sci_rnc->sm, SCI_RNC_AWAIT_SUSPENSION); 658 659 return SCI_SUCCESS; 660 } 661 662 enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *sci_rnc, 663 scics_sds_remote_node_context_callback cb_fn, 664 void *cb_p) 665 { 666 enum scis_sds_remote_node_context_states state; 667 struct isci_remote_device *idev = rnc_to_dev(sci_rnc); 668 669 state = sci_rnc->sm.current_state_id; 670 dev_dbg(scirdev_to_dev(idev), 671 "%s: state %s, cb_fn = %p, cb_p = %p; dest_state = %d; " 672 "dev resume path %s\n", 673 __func__, rnc_state_name(state), cb_fn, cb_p, 674 sci_rnc->destination_state, 675 test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags) 676 ? "<abort active>" : "<normal>"); 677 678 switch (state) { 679 case SCI_RNC_INITIAL: 680 if (sci_rnc->remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) 681 return SCI_FAILURE_INVALID_STATE; 682 683 sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p, 684 RNC_DEST_READY); 685 if (!test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) { 686 sci_remote_node_context_construct_buffer(sci_rnc); 687 sci_change_state(&sci_rnc->sm, SCI_RNC_POSTING); 688 } 689 return SCI_SUCCESS; 690 691 case SCI_RNC_POSTING: 692 case SCI_RNC_INVALIDATING: 693 case SCI_RNC_RESUMING: 694 /* We are still waiting to post when a resume was 695 * requested. 696 */ 697 switch (sci_rnc->destination_state) { 698 case RNC_DEST_SUSPENDED: 699 case RNC_DEST_SUSPENDED_RESUME: 700 /* Previously waiting to suspend after posting. 701 * Now continue onto resumption. 702 */ 703 sci_remote_node_context_setup_to_resume( 704 sci_rnc, cb_fn, cb_p, 705 RNC_DEST_SUSPENDED_RESUME); 706 break; 707 default: 708 sci_remote_node_context_setup_to_resume( 709 sci_rnc, cb_fn, cb_p, 710 RNC_DEST_READY); 711 break; 712 } 713 return SCI_SUCCESS; 714 715 case SCI_RNC_TX_SUSPENDED: 716 case SCI_RNC_TX_RX_SUSPENDED: 717 { 718 struct domain_device *dev = idev->domain_dev; 719 /* If this is an expander attached SATA device we must 720 * invalidate and repost the RNC since this is the only 721 * way to clear the TCi to NCQ tag mapping table for 722 * the RNi. All other device types we can just resume. 723 */ 724 sci_remote_node_context_setup_to_resume( 725 sci_rnc, cb_fn, cb_p, RNC_DEST_READY); 726 727 if (!test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) { 728 if ((dev_is_sata(dev) && dev->parent) || 729 (sci_rnc->destination_state == RNC_DEST_FINAL)) 730 sci_change_state(&sci_rnc->sm, 731 SCI_RNC_INVALIDATING); 732 else 733 sci_change_state(&sci_rnc->sm, 734 SCI_RNC_RESUMING); 735 } 736 } 737 return SCI_SUCCESS; 738 739 case SCI_RNC_AWAIT_SUSPENSION: 740 sci_remote_node_context_setup_to_resume( 741 sci_rnc, cb_fn, cb_p, RNC_DEST_SUSPENDED_RESUME); 742 return SCI_SUCCESS; 743 default: 744 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), 745 "%s: invalid state %s\n", __func__, 746 rnc_state_name(state)); 747 return SCI_FAILURE_INVALID_STATE; 748 } 749 } 750 751 enum sci_status sci_remote_node_context_start_io(struct sci_remote_node_context *sci_rnc, 752 struct isci_request *ireq) 753 { 754 enum scis_sds_remote_node_context_states state; 755 756 state = sci_rnc->sm.current_state_id; 757 758 switch (state) { 759 case SCI_RNC_READY: 760 return SCI_SUCCESS; 761 case SCI_RNC_TX_SUSPENDED: 762 case SCI_RNC_TX_RX_SUSPENDED: 763 case SCI_RNC_AWAIT_SUSPENSION: 764 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), 765 "%s: invalid state %s\n", __func__, 766 rnc_state_name(state)); 767 return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED; 768 default: 769 dev_dbg(scirdev_to_dev(rnc_to_dev(sci_rnc)), 770 "%s: invalid state %s\n", __func__, 771 rnc_state_name(state)); 772 return SCI_FAILURE_INVALID_STATE; 773 } 774 } 775 776 enum sci_status sci_remote_node_context_start_task( 777 struct sci_remote_node_context *sci_rnc, 778 struct isci_request *ireq, 779 scics_sds_remote_node_context_callback cb_fn, 780 void *cb_p) 781 { 782 enum sci_status status = sci_remote_node_context_resume(sci_rnc, 783 cb_fn, cb_p); 784 if (status != SCI_SUCCESS) 785 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), 786 "%s: resume failed: %d\n", __func__, status); 787 return status; 788 } 789 790 int sci_remote_node_context_is_safe_to_abort( 791 struct sci_remote_node_context *sci_rnc) 792 { 793 enum scis_sds_remote_node_context_states state; 794 795 state = sci_rnc->sm.current_state_id; 796 switch (state) { 797 case SCI_RNC_INVALIDATING: 798 case SCI_RNC_TX_RX_SUSPENDED: 799 return 1; 800 case SCI_RNC_POSTING: 801 case SCI_RNC_RESUMING: 802 case SCI_RNC_READY: 803 case SCI_RNC_TX_SUSPENDED: 804 case SCI_RNC_AWAIT_SUSPENSION: 805 case SCI_RNC_INITIAL: 806 return 0; 807 default: 808 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), 809 "%s: invalid state %d\n", __func__, state); 810 return 0; 811 } 812 } 813