Commit 6c6aacbb authored by Jeff Skirvin's avatar Jeff Skirvin Committed by Dan Williams

isci: Fixed RNC bug that lost the suspension or resumption during destroy

This fix corrects the saving of resume parameters when the destruction
of the RNC has already been directed, and makes sure not to overwrite
the RNC destruction callbacks.
Signed-off-by: default avatarJeff Skirvin <jeffrey.d.skirvin@intel.com>
Signed-off-by: default avatarDan Williams <dan.j.williams@intel.com>
parent 79cbab89
...@@ -160,15 +160,6 @@ static void sci_remote_node_context_construct_buffer(struct sci_remote_node_cont ...@@ -160,15 +160,6 @@ static void sci_remote_node_context_construct_buffer(struct sci_remote_node_cont
rnc->ssp.oaf_source_zone_group = 0; rnc->ssp.oaf_source_zone_group = 0;
rnc->ssp.oaf_more_compatibility_features = 0; rnc->ssp.oaf_more_compatibility_features = 0;
} }
static void sci_remote_node_context_save_cbparams(
struct sci_remote_node_context *sci_rnc,
scics_sds_remote_node_context_callback callback,
void *callback_parameter)
{
sci_rnc->user_callback = callback;
sci_rnc->user_cookie = callback_parameter;
}
/** /**
* *
* @sci_rnc: * @sci_rnc:
...@@ -187,9 +178,10 @@ static void sci_remote_node_context_setup_to_resume( ...@@ -187,9 +178,10 @@ static void sci_remote_node_context_setup_to_resume(
{ {
if (sci_rnc->destination_state != RNC_DEST_FINAL) { if (sci_rnc->destination_state != RNC_DEST_FINAL) {
sci_rnc->destination_state = dest_param; sci_rnc->destination_state = dest_param;
if (callback != NULL) if (callback != NULL) {
sci_remote_node_context_save_cbparams( sci_rnc->user_callback = callback;
sci_rnc, callback, callback_parameter); sci_rnc->user_cookie = callback_parameter;
}
} }
} }
...@@ -610,7 +602,8 @@ enum sci_status sci_remote_node_context_suspend( ...@@ -610,7 +602,8 @@ enum sci_status sci_remote_node_context_suspend(
* entry into the SCI_RNC_READY state that a suspension * entry into the SCI_RNC_READY state that a suspension
* needs to be done immediately. * needs to be done immediately.
*/ */
sci_rnc->destination_state = RNC_DEST_SUSPENDED; if (sci_rnc->destination_state != RNC_DEST_FINAL)
sci_rnc->destination_state = RNC_DEST_SUSPENDED;
sci_rnc->suspend_type = suspend_type; sci_rnc->suspend_type = suspend_type;
sci_rnc->suspend_reason = suspend_reason; sci_rnc->suspend_reason = suspend_reason;
return SCI_SUCCESS; return SCI_SUCCESS;
...@@ -680,12 +673,9 @@ enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *s ...@@ -680,12 +673,9 @@ enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *s
if (sci_rnc->remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) if (sci_rnc->remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX)
return SCI_FAILURE_INVALID_STATE; return SCI_FAILURE_INVALID_STATE;
if (test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p,
sci_remote_node_context_save_cbparams(sci_rnc, cb_fn, RNC_DEST_READY);
cb_p); if (!test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) {
else {
sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn,
cb_p, RNC_DEST_READY);
sci_remote_node_context_construct_buffer(sci_rnc); sci_remote_node_context_construct_buffer(sci_rnc);
sci_change_state(&sci_rnc->sm, SCI_RNC_POSTING); sci_change_state(&sci_rnc->sm, SCI_RNC_POSTING);
} }
...@@ -694,38 +684,30 @@ enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *s ...@@ -694,38 +684,30 @@ enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *s
case SCI_RNC_POSTING: case SCI_RNC_POSTING:
case SCI_RNC_INVALIDATING: case SCI_RNC_INVALIDATING:
case SCI_RNC_RESUMING: case SCI_RNC_RESUMING:
if (test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) /* We are still waiting to post when a resume was
sci_remote_node_context_save_cbparams(sci_rnc, cb_fn, * requested.
cb_p); */
else { switch (sci_rnc->destination_state) {
/* We are still waiting to post when a resume was case RNC_DEST_SUSPENDED:
* requested. case RNC_DEST_SUSPENDED_RESUME:
/* Previously waiting to suspend after posting.
* Now continue onto resumption.
*/ */
switch (sci_rnc->destination_state) { sci_remote_node_context_setup_to_resume(
case RNC_DEST_SUSPENDED: sci_rnc, cb_fn, cb_p,
case RNC_DEST_SUSPENDED_RESUME: RNC_DEST_SUSPENDED_RESUME);
/* Previously waiting to suspend after posting. break;
* Now continue onto resumption. default:
*/ sci_remote_node_context_setup_to_resume(
sci_remote_node_context_setup_to_resume( sci_rnc, cb_fn, cb_p,
sci_rnc, cb_fn, cb_p, RNC_DEST_READY);
RNC_DEST_SUSPENDED_RESUME); break;
break;
default:
sci_remote_node_context_setup_to_resume(
sci_rnc, cb_fn, cb_p,
RNC_DEST_READY);
break;
}
} }
return SCI_SUCCESS; return SCI_SUCCESS;
case SCI_RNC_TX_SUSPENDED: case SCI_RNC_TX_SUSPENDED:
case SCI_RNC_TX_RX_SUSPENDED: case SCI_RNC_TX_RX_SUSPENDED:
if (test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) {
sci_remote_node_context_save_cbparams(sci_rnc, cb_fn,
cb_p);
else {
struct domain_device *dev = idev->domain_dev; struct domain_device *dev = idev->domain_dev;
/* If this is an expander attached SATA device we must /* If this is an expander attached SATA device we must
* invalidate and repost the RNC since this is the only * invalidate and repost the RNC since this is the only
...@@ -735,23 +717,21 @@ enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *s ...@@ -735,23 +717,21 @@ enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *s
sci_remote_node_context_setup_to_resume( sci_remote_node_context_setup_to_resume(
sci_rnc, cb_fn, cb_p, RNC_DEST_READY); sci_rnc, cb_fn, cb_p, RNC_DEST_READY);
if (dev_is_sata(dev) && dev->parent) if (!test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) {
sci_change_state(&sci_rnc->sm, if ((dev_is_sata(dev) && dev->parent) ||
SCI_RNC_INVALIDATING); (sci_rnc->destination_state == RNC_DEST_FINAL))
else sci_change_state(&sci_rnc->sm,
sci_change_state(&sci_rnc->sm, SCI_RNC_INVALIDATING);
SCI_RNC_RESUMING); else
sci_change_state(&sci_rnc->sm,
SCI_RNC_RESUMING);
}
} }
return SCI_SUCCESS; return SCI_SUCCESS;
case SCI_RNC_AWAIT_SUSPENSION: case SCI_RNC_AWAIT_SUSPENSION:
if (test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) sci_remote_node_context_setup_to_resume(
sci_remote_node_context_save_cbparams(sci_rnc, cb_fn, sci_rnc, cb_fn, cb_p, RNC_DEST_SUSPENDED_RESUME);
cb_p);
else
sci_remote_node_context_setup_to_resume(
sci_rnc, cb_fn, cb_p,
RNC_DEST_SUSPENDED_RESUME);
return SCI_SUCCESS; return SCI_SUCCESS;
default: default:
dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment