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: Jeff Skirvin <jeffrey.d.skirvin@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
Jeff Skirvin 2012-03-13 17:03:00 -07:00 committed by Dan Williams
parent 79cbab89ff
commit 6c6aacbb77
1 changed files with 38 additions and 58 deletions

View File

@ -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_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:
@ -187,9 +178,10 @@ static void sci_remote_node_context_setup_to_resume(
{
if (sci_rnc->destination_state != RNC_DEST_FINAL) {
sci_rnc->destination_state = dest_param;
if (callback != NULL)
sci_remote_node_context_save_cbparams(
sci_rnc, callback, callback_parameter);
if (callback != NULL) {
sci_rnc->user_callback = callback;
sci_rnc->user_cookie = callback_parameter;
}
}
}
@ -610,7 +602,8 @@ enum sci_status sci_remote_node_context_suspend(
* entry into the SCI_RNC_READY state that a suspension
* 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_reason = suspend_reason;
return SCI_SUCCESS;
@ -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)
return SCI_FAILURE_INVALID_STATE;
if (test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags))
sci_remote_node_context_save_cbparams(sci_rnc, cb_fn,
cb_p);
else {
sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn,
cb_p, RNC_DEST_READY);
sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p,
RNC_DEST_READY);
if (!test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) {
sci_remote_node_context_construct_buffer(sci_rnc);
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
case SCI_RNC_POSTING:
case SCI_RNC_INVALIDATING:
case SCI_RNC_RESUMING:
if (test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags))
sci_remote_node_context_save_cbparams(sci_rnc, cb_fn,
cb_p);
else {
/* We are still waiting to post when a resume was
* requested.
/* 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.
* Now continue onto resumption.
*/
switch (sci_rnc->destination_state) {
case RNC_DEST_SUSPENDED:
case RNC_DEST_SUSPENDED_RESUME:
/* Previously waiting to suspend after posting.
* Now continue onto resumption.
*/
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;
}
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:
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;
/* If this is an expander attached SATA device we must
* 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
sci_remote_node_context_setup_to_resume(
sci_rnc, cb_fn, cb_p, RNC_DEST_READY);
if (dev_is_sata(dev) && dev->parent)
sci_change_state(&sci_rnc->sm,
SCI_RNC_INVALIDATING);
else
sci_change_state(&sci_rnc->sm,
SCI_RNC_RESUMING);
if (!test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) {
if ((dev_is_sata(dev) && dev->parent) ||
(sci_rnc->destination_state == RNC_DEST_FINAL))
sci_change_state(&sci_rnc->sm,
SCI_RNC_INVALIDATING);
else
sci_change_state(&sci_rnc->sm,
SCI_RNC_RESUMING);
}
}
return SCI_SUCCESS;
case SCI_RNC_AWAIT_SUSPENSION:
if (test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags))
sci_remote_node_context_save_cbparams(sci_rnc, cb_fn,
cb_p);
else
sci_remote_node_context_setup_to_resume(
sci_rnc, cb_fn, cb_p,
RNC_DEST_SUSPENDED_RESUME);
sci_remote_node_context_setup_to_resume(
sci_rnc, cb_fn, cb_p, RNC_DEST_SUSPENDED_RESUME);
return SCI_SUCCESS;
default:
dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),