aboutsummaryrefslogtreecommitdiff
path: root/drivers/scsi/isci
diff options
context:
space:
mode:
authorJeff Skirvin <jeffrey.d.skirvin@intel.com>2012-03-13 17:03:00 -0700
committerDan Williams <dan.j.williams@intel.com>2012-05-17 14:33:44 -0700
commit6c6aacbb7787dccc6fb662bae66e599bbf0f07b5 (patch)
treeec1c60ef970f55d2bb09901fc66f4efca8e09865 /drivers/scsi/isci
parent79cbab89ff31b6c6ab896d4ed5e3b2ae65193a96 (diff)
downloadlinux-linaro-stable-6c6aacbb7787dccc6fb662bae66e599bbf0f07b5.tar.gz
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>
Diffstat (limited to 'drivers/scsi/isci')
-rw-r--r--drivers/scsi/isci/remote_node_context.c96
1 files changed, 38 insertions, 58 deletions
diff --git a/drivers/scsi/isci/remote_node_context.c b/drivers/scsi/isci/remote_node_context.c
index 6f0b61b2cca8..f5792a901e02 100644
--- a/drivers/scsi/isci/remote_node_context.c
+++ b/drivers/scsi/isci/remote_node_context.c
@@ -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)),