From 6c6aacbb7787dccc6fb662bae66e599bbf0f07b5 Mon Sep 17 00:00:00 2001 From: Jeff Skirvin Date: Tue, 13 Mar 2012 17:03:00 -0700 Subject: 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 Signed-off-by: Dan Williams --- drivers/scsi/isci/remote_node_context.c | 96 +++++++++++++-------------------- 1 file changed, 38 insertions(+), 58 deletions(-) (limited to 'drivers/scsi/isci') 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)), -- cgit v1.2.3