/* sas address is __be64, context ram format is __le64 */
sas_addr = cpu_to_le64(SAS_ADDR(dev->sas_addr));
rnc->ssp.remote_sas_address_hi = upper_32_bits(sas_addr);
rnc->ssp.remote_sas_address_lo = lower_32_bits(sas_addr);
/* Check to see if we have gotten back to the initial state because *someonerequestedtodestroytheremotenodecontextobject.
*/ if (sm->previous_state_id == SCI_RNC_INVALIDATING) {
rnc->destination_state = RNC_DEST_UNSPECIFIED;
sci_remote_node_context_notify_user(rnc);
state = sci_rnc->sm.current_state_id; switch (state) { case SCI_RNC_POSTING: switch (scu_get_event_code(event_code)) { case SCU_EVENT_POST_RNC_COMPLETE:
sci_change_state(&sci_rnc->sm, SCI_RNC_READY); break; default: goto out;
} break; case SCI_RNC_INVALIDATING: if (scu_get_event_code(event_code) == SCU_EVENT_POST_RNC_INVALIDATE_COMPLETE) { if (sci_rnc->destination_state == RNC_DEST_FINAL)
next_state = SCI_RNC_INITIAL; else
next_state = SCI_RNC_POSTING;
sci_change_state(&sci_rnc->sm, next_state);
} else { switch (scu_get_event_type(event_code)) { case SCU_EVENT_TYPE_RNC_SUSPEND_TX: case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX: /* We really dont care if the hardware is going to suspend
* the device since it's being invalidated anyway */
dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), "%s: SCIC Remote Node Context 0x%p was " "suspended by hardware while being " "invalidated.\n", __func__, sci_rnc); break; default: goto out;
}
} break; case SCI_RNC_RESUMING: if (scu_get_event_code(event_code) == SCU_EVENT_POST_RCN_RELEASE) {
sci_change_state(&sci_rnc->sm, SCI_RNC_READY);
} else { switch (scu_get_event_type(event_code)) { case SCU_EVENT_TYPE_RNC_SUSPEND_TX: case SCU_EVENT_TYPE_RNC_SUSPEND_TX_RX: /* We really dont care if the hardware is going to suspend
* the device since it's being resumed anyway */
dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), "%s: SCIC Remote Node Context 0x%p was " "suspended by hardware while being resumed.\n",
__func__, sci_rnc); break; default: goto out;
}
} break; case SCI_RNC_READY: switch (scu_get_event_type(event_code)) { case SCU_EVENT_TL_RNC_SUSPEND_TX:
sci_change_state(&sci_rnc->sm, SCI_RNC_TX_SUSPENDED);
sci_rnc->suspend_type = scu_get_event_type(event_code); break; case SCU_EVENT_TL_RNC_SUSPEND_TX_RX:
sci_change_state(&sci_rnc->sm, SCI_RNC_TX_RX_SUSPENDED);
sci_rnc->suspend_type = scu_get_event_type(event_code); break; default: goto out;
} break; case SCI_RNC_AWAIT_SUSPENSION: switch (scu_get_event_type(event_code)) { case SCU_EVENT_TL_RNC_SUSPEND_TX:
next_state = SCI_RNC_TX_SUSPENDED; break; case SCU_EVENT_TL_RNC_SUSPEND_TX_RX:
next_state = SCI_RNC_TX_RX_SUSPENDED; break; default: goto out;
} if (sci_rnc->suspend_type == scu_get_event_type(event_code))
sci_change_state(&sci_rnc->sm, next_state); break; default:
dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), "%s: invalid state: %s\n", __func__,
rnc_state_name(state)); return SCI_FAILURE_INVALID_STATE;
} return SCI_SUCCESS;
state = sci_rnc->sm.current_state_id; switch (state) { case SCI_RNC_INVALIDATING:
sci_remote_node_context_setup_to_destroy(sci_rnc, cb_fn, cb_p); return SCI_SUCCESS; case SCI_RNC_POSTING: case SCI_RNC_RESUMING: case SCI_RNC_READY: case SCI_RNC_TX_SUSPENDED: case SCI_RNC_TX_RX_SUSPENDED:
sci_remote_node_context_setup_to_destroy(sci_rnc, cb_fn, cb_p);
sci_change_state(&sci_rnc->sm, SCI_RNC_INVALIDATING); return SCI_SUCCESS; case SCI_RNC_AWAIT_SUSPENSION:
sci_remote_node_context_setup_to_destroy(sci_rnc, cb_fn, cb_p); return SCI_SUCCESS; case SCI_RNC_INITIAL:
dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), "%s: invalid state: %s\n", __func__,
rnc_state_name(state)); /* We have decided that the destruct request on the remote node context *cannotfailsinceitiseitherintheinitial/destroyedstateoris *canbedestroyed.
*/ return SCI_SUCCESS; default:
dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), "%s: invalid state %s\n", __func__,
rnc_state_name(state)); return SCI_FAILURE_INVALID_STATE;
}
}
dev_dbg(scirdev_to_dev(idev), "%s: current state %s, current suspend_type %x dest state %d," " arg suspend_reason %d, arg suspend_type %x",
__func__, rnc_state_name(state), sci_rnc->suspend_type,
sci_rnc->destination_state, suspend_reason,
suspend_type);
/* Disable automatic state continuations if explicitly suspending. */ if ((suspend_reason == SCI_HW_SUSPEND) ||
(sci_rnc->destination_state == RNC_DEST_FINAL))
dest_param = sci_rnc->destination_state;
switch (state) { case SCI_RNC_READY: break; case SCI_RNC_INVALIDATING: if (sci_rnc->destination_state == RNC_DEST_FINAL) {
dev_warn(scirdev_to_dev(idev), "%s: already destroying %p\n",
__func__, sci_rnc); return SCI_FAILURE_INVALID_STATE;
}
fallthrough; /* and handle like SCI_RNC_POSTING */ case SCI_RNC_RESUMING:
fallthrough; /* and handle like SCI_RNC_POSTING */ case SCI_RNC_POSTING: /* Set the destination state to AWAIT - this signals the *entryintotheSCI_RNC_READYstatethatasuspension *needstobedoneimmediately.
*/ if (sci_rnc->destination_state != RNC_DEST_FINAL)
sci_rnc->destination_state = RNC_DEST_SUSPENDED;
sci_rnc->suspend_type = suspend_type;
sci_rnc->suspend_reason = suspend_reason; return SCI_SUCCESS;
case SCI_RNC_TX_SUSPENDED: if (suspend_type == SCU_EVENT_TL_RNC_SUSPEND_TX)
status = SCI_SUCCESS; break; case SCI_RNC_TX_RX_SUSPENDED: if (suspend_type == SCU_EVENT_TL_RNC_SUSPEND_TX_RX)
status = SCI_SUCCESS; break; case SCI_RNC_AWAIT_SUSPENSION: if ((sci_rnc->suspend_type == SCU_EVENT_TL_RNC_SUSPEND_TX_RX)
|| (suspend_type == sci_rnc->suspend_type)) return SCI_SUCCESS; break; default:
dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), "%s: invalid state %s\n", __func__,
rnc_state_name(state)); return SCI_FAILURE_INVALID_STATE;
}
sci_rnc->destination_state = dest_param;
sci_rnc->suspend_type = suspend_type;
sci_rnc->suspend_reason = suspend_reason;
if (status == SCI_SUCCESS) { /* Already in the destination state? */ struct isci_host *ihost = idev->owning_port->owning_controller;
wake_up_all(&ihost->eventq); /* Let observers look. */ return SCI_SUCCESS;
} if ((suspend_reason == SCI_SW_SUSPEND_NORMAL) ||
(suspend_reason == SCI_SW_SUSPEND_LINKHANG_DETECT)) {
if (suspend_reason == SCI_SW_SUSPEND_LINKHANG_DETECT)
isci_dev_set_hang_detection_timeout(idev, 0x00000001);
sci_remote_device_post_request(
idev, SCI_SOFTWARE_SUSPEND_CMD);
} if (state != SCI_RNC_AWAIT_SUSPENSION)
sci_change_state(&sci_rnc->sm, SCI_RNC_AWAIT_SUSPENSION);
case SCI_RNC_POSTING: case SCI_RNC_INVALIDATING: case SCI_RNC_RESUMING: /* We are still waiting to post when a resume was *requested.
*/ switch (sci_rnc->destination_state) { case RNC_DEST_SUSPENDED: case RNC_DEST_SUSPENDED_RESUME: /* Previously waiting to suspend after posting. *Nowcontinueontoresumption.
*/
sci_remote_node_context_setup_to_resume(
sci_rnc, cb_fn, cb_p,
RNC_DEST_SUSPENDED_RESUME); break; default:
sci_remote_node_context_setup_to_resume(
sci_rnc, cb_fn, cb_p,
RNC_DEST_READY); break;
} return SCI_SUCCESS;
case SCI_RNC_TX_SUSPENDED: case SCI_RNC_TX_RX_SUSPENDED:
{ struct domain_device *dev = idev->domain_dev; /* If this is an expander attached SATA device we must *invalidateandreposttheRNCsincethisistheonly *waytocleartheTCitoNCQtagmappingtablefor *theRNi.Allotherdevicetypeswecanjustresume.
*/
sci_remote_node_context_setup_to_resume(
sci_rnc, cb_fn, cb_p, RNC_DEST_READY);
int sci_remote_node_context_is_safe_to_abort( struct sci_remote_node_context *sci_rnc)
{ enum scis_sds_remote_node_context_states state;
state = sci_rnc->sm.current_state_id; switch (state) { case SCI_RNC_INVALIDATING: case SCI_RNC_TX_RX_SUSPENDED: return1; case SCI_RNC_POSTING: case SCI_RNC_RESUMING: case SCI_RNC_READY: case SCI_RNC_TX_SUSPENDED: case SCI_RNC_AWAIT_SUSPENSION: case SCI_RNC_INITIAL: return0; default:
dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), "%s: invalid state %d\n", __func__, state); return0;
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.19 Sekunden
(vorverarbeitet am 2026-09-29)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.