0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 #include <scsi/sas_ata.h>
0056 #include "host.h"
0057 #include "isci.h"
0058 #include "remote_device.h"
0059 #include "remote_node_context.h"
0060 #include "scu_event_codes.h"
0061 #include "scu_task_context.h"
0062
0063 #undef C
0064 #define C(a) (#a)
0065 const char *rnc_state_name(enum scis_sds_remote_node_context_states state)
0066 {
0067 static const char * const strings[] = RNC_STATES;
0068
0069 if (state >= ARRAY_SIZE(strings))
0070 return "UNKNOWN";
0071
0072 return strings[state];
0073 }
0074 #undef C
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084 bool sci_remote_node_context_is_ready(
0085 struct sci_remote_node_context *sci_rnc)
0086 {
0087 u32 current_state = sci_rnc->sm.current_state_id;
0088
0089 if (current_state == SCI_RNC_READY) {
0090 return true;
0091 }
0092
0093 return false;
0094 }
0095
0096 bool sci_remote_node_context_is_suspended(struct sci_remote_node_context *sci_rnc)
0097 {
0098 u32 current_state = sci_rnc->sm.current_state_id;
0099
0100 if (current_state == SCI_RNC_TX_RX_SUSPENDED)
0101 return true;
0102 return false;
0103 }
0104
0105 static union scu_remote_node_context *sci_rnc_by_id(struct isci_host *ihost, u16 id)
0106 {
0107 if (id < ihost->remote_node_entries &&
0108 ihost->device_table[id])
0109 return &ihost->remote_node_context_table[id];
0110
0111 return NULL;
0112 }
0113
0114 static void sci_remote_node_context_construct_buffer(struct sci_remote_node_context *sci_rnc)
0115 {
0116 struct isci_remote_device *idev = rnc_to_dev(sci_rnc);
0117 struct domain_device *dev = idev->domain_dev;
0118 int rni = sci_rnc->remote_node_index;
0119 union scu_remote_node_context *rnc;
0120 struct isci_host *ihost;
0121 __le64 sas_addr;
0122
0123 ihost = idev->owning_port->owning_controller;
0124 rnc = sci_rnc_by_id(ihost, rni);
0125
0126 memset(rnc, 0, sizeof(union scu_remote_node_context)
0127 * sci_remote_device_node_count(idev));
0128
0129 rnc->ssp.remote_node_index = rni;
0130 rnc->ssp.remote_node_port_width = idev->device_port_width;
0131 rnc->ssp.logical_port_index = idev->owning_port->physical_port_index;
0132
0133
0134 sas_addr = cpu_to_le64(SAS_ADDR(dev->sas_addr));
0135 rnc->ssp.remote_sas_address_hi = upper_32_bits(sas_addr);
0136 rnc->ssp.remote_sas_address_lo = lower_32_bits(sas_addr);
0137
0138 rnc->ssp.nexus_loss_timer_enable = true;
0139 rnc->ssp.check_bit = false;
0140 rnc->ssp.is_valid = false;
0141 rnc->ssp.is_remote_node_context = true;
0142 rnc->ssp.function_number = 0;
0143
0144 rnc->ssp.arbitration_wait_time = 0;
0145
0146 if (dev_is_sata(dev)) {
0147 rnc->ssp.connection_occupancy_timeout =
0148 ihost->user_parameters.stp_max_occupancy_timeout;
0149 rnc->ssp.connection_inactivity_timeout =
0150 ihost->user_parameters.stp_inactivity_timeout;
0151 } else {
0152 rnc->ssp.connection_occupancy_timeout =
0153 ihost->user_parameters.ssp_max_occupancy_timeout;
0154 rnc->ssp.connection_inactivity_timeout =
0155 ihost->user_parameters.ssp_inactivity_timeout;
0156 }
0157
0158 rnc->ssp.initial_arbitration_wait_time = 0;
0159
0160
0161 rnc->ssp.oaf_connection_rate = idev->connection_rate;
0162 rnc->ssp.oaf_features = 0;
0163 rnc->ssp.oaf_source_zone_group = 0;
0164 rnc->ssp.oaf_more_compatibility_features = 0;
0165 }
0166
0167
0168
0169
0170
0171 static void sci_remote_node_context_setup_to_resume(
0172 struct sci_remote_node_context *sci_rnc,
0173 scics_sds_remote_node_context_callback callback,
0174 void *callback_parameter,
0175 enum sci_remote_node_context_destination_state dest_param)
0176 {
0177 if (sci_rnc->destination_state != RNC_DEST_FINAL) {
0178 sci_rnc->destination_state = dest_param;
0179 if (callback != NULL) {
0180 sci_rnc->user_callback = callback;
0181 sci_rnc->user_cookie = callback_parameter;
0182 }
0183 }
0184 }
0185
0186 static void sci_remote_node_context_setup_to_destroy(
0187 struct sci_remote_node_context *sci_rnc,
0188 scics_sds_remote_node_context_callback callback,
0189 void *callback_parameter)
0190 {
0191 struct isci_host *ihost = idev_to_ihost(rnc_to_dev(sci_rnc));
0192
0193 sci_rnc->destination_state = RNC_DEST_FINAL;
0194 sci_rnc->user_callback = callback;
0195 sci_rnc->user_cookie = callback_parameter;
0196
0197 wake_up(&ihost->eventq);
0198 }
0199
0200
0201
0202
0203
0204 static void sci_remote_node_context_notify_user(
0205 struct sci_remote_node_context *rnc)
0206 {
0207 if (rnc->user_callback != NULL) {
0208 (*rnc->user_callback)(rnc->user_cookie);
0209
0210 rnc->user_callback = NULL;
0211 rnc->user_cookie = NULL;
0212 }
0213 }
0214
0215 static void sci_remote_node_context_continue_state_transitions(struct sci_remote_node_context *rnc)
0216 {
0217 switch (rnc->destination_state) {
0218 case RNC_DEST_READY:
0219 case RNC_DEST_SUSPENDED_RESUME:
0220 rnc->destination_state = RNC_DEST_READY;
0221 fallthrough;
0222 case RNC_DEST_FINAL:
0223 sci_remote_node_context_resume(rnc, rnc->user_callback,
0224 rnc->user_cookie);
0225 break;
0226 default:
0227 rnc->destination_state = RNC_DEST_UNSPECIFIED;
0228 break;
0229 }
0230 }
0231
0232 static void sci_remote_node_context_validate_context_buffer(struct sci_remote_node_context *sci_rnc)
0233 {
0234 union scu_remote_node_context *rnc_buffer;
0235 struct isci_remote_device *idev = rnc_to_dev(sci_rnc);
0236 struct domain_device *dev = idev->domain_dev;
0237 struct isci_host *ihost = idev->owning_port->owning_controller;
0238
0239 rnc_buffer = sci_rnc_by_id(ihost, sci_rnc->remote_node_index);
0240
0241 rnc_buffer->ssp.is_valid = true;
0242
0243 if (dev_is_sata(dev) && dev->parent) {
0244 sci_remote_device_post_request(idev, SCU_CONTEXT_COMMAND_POST_RNC_96);
0245 } else {
0246 sci_remote_device_post_request(idev, SCU_CONTEXT_COMMAND_POST_RNC_32);
0247
0248 if (!dev->parent)
0249 sci_port_setup_transports(idev->owning_port,
0250 sci_rnc->remote_node_index);
0251 }
0252 }
0253
0254 static void sci_remote_node_context_invalidate_context_buffer(struct sci_remote_node_context *sci_rnc)
0255 {
0256 union scu_remote_node_context *rnc_buffer;
0257 struct isci_remote_device *idev = rnc_to_dev(sci_rnc);
0258 struct isci_host *ihost = idev->owning_port->owning_controller;
0259
0260 rnc_buffer = sci_rnc_by_id(ihost, sci_rnc->remote_node_index);
0261
0262 rnc_buffer->ssp.is_valid = false;
0263
0264 sci_remote_device_post_request(rnc_to_dev(sci_rnc),
0265 SCU_CONTEXT_COMMAND_POST_RNC_INVALIDATE);
0266 }
0267
0268 static void sci_remote_node_context_initial_state_enter(struct sci_base_state_machine *sm)
0269 {
0270 struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm);
0271 struct isci_remote_device *idev = rnc_to_dev(rnc);
0272 struct isci_host *ihost = idev->owning_port->owning_controller;
0273
0274
0275
0276
0277 if (sm->previous_state_id == SCI_RNC_INVALIDATING) {
0278 rnc->destination_state = RNC_DEST_UNSPECIFIED;
0279 sci_remote_node_context_notify_user(rnc);
0280
0281 smp_wmb();
0282 wake_up(&ihost->eventq);
0283 }
0284 }
0285
0286 static void sci_remote_node_context_posting_state_enter(struct sci_base_state_machine *sm)
0287 {
0288 struct sci_remote_node_context *sci_rnc = container_of(sm, typeof(*sci_rnc), sm);
0289
0290 sci_remote_node_context_validate_context_buffer(sci_rnc);
0291 }
0292
0293 static void sci_remote_node_context_invalidating_state_enter(struct sci_base_state_machine *sm)
0294 {
0295 struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm);
0296
0297
0298 sci_remote_device_terminate_requests(rnc_to_dev(rnc));
0299 sci_remote_node_context_invalidate_context_buffer(rnc);
0300 }
0301
0302 static void sci_remote_node_context_resuming_state_enter(struct sci_base_state_machine *sm)
0303 {
0304 struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm);
0305 struct isci_remote_device *idev;
0306 struct domain_device *dev;
0307
0308 idev = rnc_to_dev(rnc);
0309 dev = idev->domain_dev;
0310
0311
0312
0313
0314
0315
0316
0317 if (dev_is_sata(dev) && !dev->parent)
0318 sci_port_setup_transports(idev->owning_port, rnc->remote_node_index);
0319
0320 sci_remote_device_post_request(idev, SCU_CONTEXT_COMMAND_POST_RNC_RESUME);
0321 }
0322
0323 static void sci_remote_node_context_ready_state_enter(struct sci_base_state_machine *sm)
0324 {
0325 struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm);
0326 enum sci_remote_node_context_destination_state dest_select;
0327 int tell_user = 1;
0328
0329 dest_select = rnc->destination_state;
0330 rnc->destination_state = RNC_DEST_UNSPECIFIED;
0331
0332 if ((dest_select == RNC_DEST_SUSPENDED) ||
0333 (dest_select == RNC_DEST_SUSPENDED_RESUME)) {
0334 sci_remote_node_context_suspend(
0335 rnc, rnc->suspend_reason,
0336 SCI_SOFTWARE_SUSPEND_EXPECTED_EVENT);
0337
0338 if (dest_select == RNC_DEST_SUSPENDED_RESUME)
0339 tell_user = 0;
0340 }
0341 if (tell_user)
0342 sci_remote_node_context_notify_user(rnc);
0343 }
0344
0345 static void sci_remote_node_context_tx_suspended_state_enter(struct sci_base_state_machine *sm)
0346 {
0347 struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm);
0348
0349 sci_remote_node_context_continue_state_transitions(rnc);
0350 }
0351
0352 static void sci_remote_node_context_tx_rx_suspended_state_enter(struct sci_base_state_machine *sm)
0353 {
0354 struct sci_remote_node_context *rnc = container_of(sm, typeof(*rnc), sm);
0355 struct isci_remote_device *idev = rnc_to_dev(rnc);
0356 struct isci_host *ihost = idev->owning_port->owning_controller;
0357 u32 new_count = rnc->suspend_count + 1;
0358
0359 if (new_count == 0)
0360 rnc->suspend_count = 1;
0361 else
0362 rnc->suspend_count = new_count;
0363 smp_wmb();
0364
0365
0366 sci_remote_device_abort_requests_pending_abort(idev);
0367
0368 wake_up(&ihost->eventq);
0369 sci_remote_node_context_continue_state_transitions(rnc);
0370 }
0371
0372 static void sci_remote_node_context_await_suspend_state_exit(
0373 struct sci_base_state_machine *sm)
0374 {
0375 struct sci_remote_node_context *rnc
0376 = container_of(sm, typeof(*rnc), sm);
0377 struct isci_remote_device *idev = rnc_to_dev(rnc);
0378
0379 if (dev_is_sata(idev->domain_dev))
0380 isci_dev_set_hang_detection_timeout(idev, 0);
0381 }
0382
0383 static const struct sci_base_state sci_remote_node_context_state_table[] = {
0384 [SCI_RNC_INITIAL] = {
0385 .enter_state = sci_remote_node_context_initial_state_enter,
0386 },
0387 [SCI_RNC_POSTING] = {
0388 .enter_state = sci_remote_node_context_posting_state_enter,
0389 },
0390 [SCI_RNC_INVALIDATING] = {
0391 .enter_state = sci_remote_node_context_invalidating_state_enter,
0392 },
0393 [SCI_RNC_RESUMING] = {
0394 .enter_state = sci_remote_node_context_resuming_state_enter,
0395 },
0396 [SCI_RNC_READY] = {
0397 .enter_state = sci_remote_node_context_ready_state_enter,
0398 },
0399 [SCI_RNC_TX_SUSPENDED] = {
0400 .enter_state = sci_remote_node_context_tx_suspended_state_enter,
0401 },
0402 [SCI_RNC_TX_RX_SUSPENDED] = {
0403 .enter_state = sci_remote_node_context_tx_rx_suspended_state_enter,
0404 },
0405 [SCI_RNC_AWAIT_SUSPENSION] = {
0406 .exit_state = sci_remote_node_context_await_suspend_state_exit,
0407 },
0408 };
0409
0410 void sci_remote_node_context_construct(struct sci_remote_node_context *rnc,
0411 u16 remote_node_index)
0412 {
0413 memset(rnc, 0, sizeof(struct sci_remote_node_context));
0414
0415 rnc->remote_node_index = remote_node_index;
0416 rnc->destination_state = RNC_DEST_UNSPECIFIED;
0417
0418 sci_init_sm(&rnc->sm, sci_remote_node_context_state_table, SCI_RNC_INITIAL);
0419 }
0420
0421 enum sci_status sci_remote_node_context_event_handler(struct sci_remote_node_context *sci_rnc,
0422 u32 event_code)
0423 {
0424 enum scis_sds_remote_node_context_states state;
0425 u32 next_state;
0426
0427 state = sci_rnc->sm.current_state_id;
0428 switch (state) {
0429 case SCI_RNC_POSTING:
0430 switch (scu_get_event_code(event_code)) {
0431 case SCU_EVENT_POST_RNC_COMPLETE:
0432 sci_change_state(&sci_rnc->sm, SCI_RNC_READY);
0433 break;
0434 default:
0435 goto out;
0436 }
0437 break;
0438 case SCI_RNC_INVALIDATING:
0439 if (scu_get_event_code(event_code) == SCU_EVENT_POST_RNC_INVALIDATE_COMPLETE) {
0440 if (sci_rnc->destination_state == RNC_DEST_FINAL)
0441 next_state = SCI_RNC_INITIAL;
0442 else
0443 next_state = SCI_RNC_POSTING;
0444 sci_change_state(&sci_rnc->sm, next_state);
0445 } else {
0446 switch (scu_get_event_type(event_code)) {
0447 case SCU_EVENT_TYPE_RNC_SUSPEND_TX:
0448 case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX:
0449
0450
0451 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0452 "%s: SCIC Remote Node Context 0x%p was "
0453 "suspended by hardware while being "
0454 "invalidated.\n", __func__, sci_rnc);
0455 break;
0456 default:
0457 goto out;
0458 }
0459 }
0460 break;
0461 case SCI_RNC_RESUMING:
0462 if (scu_get_event_code(event_code) == SCU_EVENT_POST_RCN_RELEASE) {
0463 sci_change_state(&sci_rnc->sm, SCI_RNC_READY);
0464 } else {
0465 switch (scu_get_event_type(event_code)) {
0466 case SCU_EVENT_TYPE_RNC_SUSPEND_TX:
0467 case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX:
0468
0469
0470 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0471 "%s: SCIC Remote Node Context 0x%p was "
0472 "suspended by hardware while being resumed.\n",
0473 __func__, sci_rnc);
0474 break;
0475 default:
0476 goto out;
0477 }
0478 }
0479 break;
0480 case SCI_RNC_READY:
0481 switch (scu_get_event_type(event_code)) {
0482 case SCU_EVENT_TL_RNC_SUSPEND_TX:
0483 sci_change_state(&sci_rnc->sm, SCI_RNC_TX_SUSPENDED);
0484 sci_rnc->suspend_type = scu_get_event_type(event_code);
0485 break;
0486 case SCU_EVENT_TL_RNC_SUSPEND_TX_RX:
0487 sci_change_state(&sci_rnc->sm, SCI_RNC_TX_RX_SUSPENDED);
0488 sci_rnc->suspend_type = scu_get_event_type(event_code);
0489 break;
0490 default:
0491 goto out;
0492 }
0493 break;
0494 case SCI_RNC_AWAIT_SUSPENSION:
0495 switch (scu_get_event_type(event_code)) {
0496 case SCU_EVENT_TL_RNC_SUSPEND_TX:
0497 next_state = SCI_RNC_TX_SUSPENDED;
0498 break;
0499 case SCU_EVENT_TL_RNC_SUSPEND_TX_RX:
0500 next_state = SCI_RNC_TX_RX_SUSPENDED;
0501 break;
0502 default:
0503 goto out;
0504 }
0505 if (sci_rnc->suspend_type == scu_get_event_type(event_code))
0506 sci_change_state(&sci_rnc->sm, next_state);
0507 break;
0508 default:
0509 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0510 "%s: invalid state: %s\n", __func__,
0511 rnc_state_name(state));
0512 return SCI_FAILURE_INVALID_STATE;
0513 }
0514 return SCI_SUCCESS;
0515
0516 out:
0517 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0518 "%s: code: %#x state: %s\n", __func__, event_code,
0519 rnc_state_name(state));
0520 return SCI_FAILURE;
0521
0522 }
0523
0524 enum sci_status sci_remote_node_context_destruct(struct sci_remote_node_context *sci_rnc,
0525 scics_sds_remote_node_context_callback cb_fn,
0526 void *cb_p)
0527 {
0528 enum scis_sds_remote_node_context_states state;
0529
0530 state = sci_rnc->sm.current_state_id;
0531 switch (state) {
0532 case SCI_RNC_INVALIDATING:
0533 sci_remote_node_context_setup_to_destroy(sci_rnc, cb_fn, cb_p);
0534 return SCI_SUCCESS;
0535 case SCI_RNC_POSTING:
0536 case SCI_RNC_RESUMING:
0537 case SCI_RNC_READY:
0538 case SCI_RNC_TX_SUSPENDED:
0539 case SCI_RNC_TX_RX_SUSPENDED:
0540 sci_remote_node_context_setup_to_destroy(sci_rnc, cb_fn, cb_p);
0541 sci_change_state(&sci_rnc->sm, SCI_RNC_INVALIDATING);
0542 return SCI_SUCCESS;
0543 case SCI_RNC_AWAIT_SUSPENSION:
0544 sci_remote_node_context_setup_to_destroy(sci_rnc, cb_fn, cb_p);
0545 return SCI_SUCCESS;
0546 case SCI_RNC_INITIAL:
0547 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0548 "%s: invalid state: %s\n", __func__,
0549 rnc_state_name(state));
0550
0551
0552
0553
0554 return SCI_SUCCESS;
0555 default:
0556 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0557 "%s: invalid state %s\n", __func__,
0558 rnc_state_name(state));
0559 return SCI_FAILURE_INVALID_STATE;
0560 }
0561 }
0562
0563 enum sci_status sci_remote_node_context_suspend(
0564 struct sci_remote_node_context *sci_rnc,
0565 enum sci_remote_node_suspension_reasons suspend_reason,
0566 u32 suspend_type)
0567 {
0568 enum scis_sds_remote_node_context_states state
0569 = sci_rnc->sm.current_state_id;
0570 struct isci_remote_device *idev = rnc_to_dev(sci_rnc);
0571 enum sci_status status = SCI_FAILURE_INVALID_STATE;
0572 enum sci_remote_node_context_destination_state dest_param =
0573 RNC_DEST_UNSPECIFIED;
0574
0575 dev_dbg(scirdev_to_dev(idev),
0576 "%s: current state %s, current suspend_type %x dest state %d,"
0577 " arg suspend_reason %d, arg suspend_type %x",
0578 __func__, rnc_state_name(state), sci_rnc->suspend_type,
0579 sci_rnc->destination_state, suspend_reason,
0580 suspend_type);
0581
0582
0583 if ((suspend_reason == SCI_HW_SUSPEND) ||
0584 (sci_rnc->destination_state == RNC_DEST_FINAL))
0585 dest_param = sci_rnc->destination_state;
0586
0587 switch (state) {
0588 case SCI_RNC_READY:
0589 break;
0590 case SCI_RNC_INVALIDATING:
0591 if (sci_rnc->destination_state == RNC_DEST_FINAL) {
0592 dev_warn(scirdev_to_dev(idev),
0593 "%s: already destroying %p\n",
0594 __func__, sci_rnc);
0595 return SCI_FAILURE_INVALID_STATE;
0596 }
0597 fallthrough;
0598 case SCI_RNC_RESUMING:
0599 fallthrough;
0600 case SCI_RNC_POSTING:
0601
0602
0603
0604
0605 if (sci_rnc->destination_state != RNC_DEST_FINAL)
0606 sci_rnc->destination_state = RNC_DEST_SUSPENDED;
0607 sci_rnc->suspend_type = suspend_type;
0608 sci_rnc->suspend_reason = suspend_reason;
0609 return SCI_SUCCESS;
0610
0611 case SCI_RNC_TX_SUSPENDED:
0612 if (suspend_type == SCU_EVENT_TL_RNC_SUSPEND_TX)
0613 status = SCI_SUCCESS;
0614 break;
0615 case SCI_RNC_TX_RX_SUSPENDED:
0616 if (suspend_type == SCU_EVENT_TL_RNC_SUSPEND_TX_RX)
0617 status = SCI_SUCCESS;
0618 break;
0619 case SCI_RNC_AWAIT_SUSPENSION:
0620 if ((sci_rnc->suspend_type == SCU_EVENT_TL_RNC_SUSPEND_TX_RX)
0621 || (suspend_type == sci_rnc->suspend_type))
0622 return SCI_SUCCESS;
0623 break;
0624 default:
0625 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0626 "%s: invalid state %s\n", __func__,
0627 rnc_state_name(state));
0628 return SCI_FAILURE_INVALID_STATE;
0629 }
0630 sci_rnc->destination_state = dest_param;
0631 sci_rnc->suspend_type = suspend_type;
0632 sci_rnc->suspend_reason = suspend_reason;
0633
0634 if (status == SCI_SUCCESS) {
0635 struct isci_host *ihost = idev->owning_port->owning_controller;
0636
0637 wake_up_all(&ihost->eventq);
0638 return SCI_SUCCESS;
0639 }
0640 if ((suspend_reason == SCI_SW_SUSPEND_NORMAL) ||
0641 (suspend_reason == SCI_SW_SUSPEND_LINKHANG_DETECT)) {
0642
0643 if (suspend_reason == SCI_SW_SUSPEND_LINKHANG_DETECT)
0644 isci_dev_set_hang_detection_timeout(idev, 0x00000001);
0645
0646 sci_remote_device_post_request(
0647 idev, SCI_SOFTWARE_SUSPEND_CMD);
0648 }
0649 if (state != SCI_RNC_AWAIT_SUSPENSION)
0650 sci_change_state(&sci_rnc->sm, SCI_RNC_AWAIT_SUSPENSION);
0651
0652 return SCI_SUCCESS;
0653 }
0654
0655 enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *sci_rnc,
0656 scics_sds_remote_node_context_callback cb_fn,
0657 void *cb_p)
0658 {
0659 enum scis_sds_remote_node_context_states state;
0660 struct isci_remote_device *idev = rnc_to_dev(sci_rnc);
0661
0662 state = sci_rnc->sm.current_state_id;
0663 dev_dbg(scirdev_to_dev(idev),
0664 "%s: state %s, cb_fn = %p, cb_p = %p; dest_state = %d; "
0665 "dev resume path %s\n",
0666 __func__, rnc_state_name(state), cb_fn, cb_p,
0667 sci_rnc->destination_state,
0668 test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)
0669 ? "<abort active>" : "<normal>");
0670
0671 switch (state) {
0672 case SCI_RNC_INITIAL:
0673 if (sci_rnc->remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX)
0674 return SCI_FAILURE_INVALID_STATE;
0675
0676 sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p,
0677 RNC_DEST_READY);
0678 if (!test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) {
0679 sci_remote_node_context_construct_buffer(sci_rnc);
0680 sci_change_state(&sci_rnc->sm, SCI_RNC_POSTING);
0681 }
0682 return SCI_SUCCESS;
0683
0684 case SCI_RNC_POSTING:
0685 case SCI_RNC_INVALIDATING:
0686 case SCI_RNC_RESUMING:
0687
0688
0689
0690 switch (sci_rnc->destination_state) {
0691 case RNC_DEST_SUSPENDED:
0692 case RNC_DEST_SUSPENDED_RESUME:
0693
0694
0695
0696 sci_remote_node_context_setup_to_resume(
0697 sci_rnc, cb_fn, cb_p,
0698 RNC_DEST_SUSPENDED_RESUME);
0699 break;
0700 default:
0701 sci_remote_node_context_setup_to_resume(
0702 sci_rnc, cb_fn, cb_p,
0703 RNC_DEST_READY);
0704 break;
0705 }
0706 return SCI_SUCCESS;
0707
0708 case SCI_RNC_TX_SUSPENDED:
0709 case SCI_RNC_TX_RX_SUSPENDED:
0710 {
0711 struct domain_device *dev = idev->domain_dev;
0712
0713
0714
0715
0716
0717 sci_remote_node_context_setup_to_resume(
0718 sci_rnc, cb_fn, cb_p, RNC_DEST_READY);
0719
0720 if (!test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) {
0721 if ((dev_is_sata(dev) && dev->parent) ||
0722 (sci_rnc->destination_state == RNC_DEST_FINAL))
0723 sci_change_state(&sci_rnc->sm,
0724 SCI_RNC_INVALIDATING);
0725 else
0726 sci_change_state(&sci_rnc->sm,
0727 SCI_RNC_RESUMING);
0728 }
0729 }
0730 return SCI_SUCCESS;
0731
0732 case SCI_RNC_AWAIT_SUSPENSION:
0733 sci_remote_node_context_setup_to_resume(
0734 sci_rnc, cb_fn, cb_p, RNC_DEST_SUSPENDED_RESUME);
0735 return SCI_SUCCESS;
0736 default:
0737 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0738 "%s: invalid state %s\n", __func__,
0739 rnc_state_name(state));
0740 return SCI_FAILURE_INVALID_STATE;
0741 }
0742 }
0743
0744 enum sci_status sci_remote_node_context_start_io(struct sci_remote_node_context *sci_rnc,
0745 struct isci_request *ireq)
0746 {
0747 enum scis_sds_remote_node_context_states state;
0748
0749 state = sci_rnc->sm.current_state_id;
0750
0751 switch (state) {
0752 case SCI_RNC_READY:
0753 return SCI_SUCCESS;
0754 case SCI_RNC_TX_SUSPENDED:
0755 case SCI_RNC_TX_RX_SUSPENDED:
0756 case SCI_RNC_AWAIT_SUSPENSION:
0757 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0758 "%s: invalid state %s\n", __func__,
0759 rnc_state_name(state));
0760 return SCI_FAILURE_REMOTE_DEVICE_RESET_REQUIRED;
0761 default:
0762 dev_dbg(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0763 "%s: invalid state %s\n", __func__,
0764 rnc_state_name(state));
0765 return SCI_FAILURE_INVALID_STATE;
0766 }
0767 }
0768
0769 enum sci_status sci_remote_node_context_start_task(
0770 struct sci_remote_node_context *sci_rnc,
0771 struct isci_request *ireq,
0772 scics_sds_remote_node_context_callback cb_fn,
0773 void *cb_p)
0774 {
0775 enum sci_status status = sci_remote_node_context_resume(sci_rnc,
0776 cb_fn, cb_p);
0777 if (status != SCI_SUCCESS)
0778 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0779 "%s: resume failed: %d\n", __func__, status);
0780 return status;
0781 }
0782
0783 int sci_remote_node_context_is_safe_to_abort(
0784 struct sci_remote_node_context *sci_rnc)
0785 {
0786 enum scis_sds_remote_node_context_states state;
0787
0788 state = sci_rnc->sm.current_state_id;
0789 switch (state) {
0790 case SCI_RNC_INVALIDATING:
0791 case SCI_RNC_TX_RX_SUSPENDED:
0792 return 1;
0793 case SCI_RNC_POSTING:
0794 case SCI_RNC_RESUMING:
0795 case SCI_RNC_READY:
0796 case SCI_RNC_TX_SUSPENDED:
0797 case SCI_RNC_AWAIT_SUSPENSION:
0798 case SCI_RNC_INITIAL:
0799 return 0;
0800 default:
0801 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
0802 "%s: invalid state %d\n", __func__, state);
0803 return 0;
0804 }
0805 }