aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci
diff options
context:
space:
mode:
authorJeff Skirvin <jeffrey.d.skirvin@intel.com>2012-03-13 20:03:00 -0400
committerDan Williams <dan.j.williams@intel.com>2012-05-17 17:33:44 -0400
commit6c6aacbb7787dccc6fb662bae66e599bbf0f07b5 (patch)
treeec1c60ef970f55d2bb09901fc66f4efca8e09865 /drivers/scsi/isci
parent79cbab89ff31b6c6ab896d4ed5e3b2ae65193a96 (diff)
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
160 rnc->ssp.oaf_source_zone_group = 0; 160 rnc->ssp.oaf_source_zone_group = 0;
161 rnc->ssp.oaf_more_compatibility_features = 0; 161 rnc->ssp.oaf_more_compatibility_features = 0;
162} 162}
163
164static void sci_remote_node_context_save_cbparams(
165 struct sci_remote_node_context *sci_rnc,
166 scics_sds_remote_node_context_callback callback,
167 void *callback_parameter)
168{
169 sci_rnc->user_callback = callback;
170 sci_rnc->user_cookie = callback_parameter;
171}
172/** 163/**
173 * 164 *
174 * @sci_rnc: 165 * @sci_rnc:
@@ -187,9 +178,10 @@ static void sci_remote_node_context_setup_to_resume(
187{ 178{
188 if (sci_rnc->destination_state != RNC_DEST_FINAL) { 179 if (sci_rnc->destination_state != RNC_DEST_FINAL) {
189 sci_rnc->destination_state = dest_param; 180 sci_rnc->destination_state = dest_param;
190 if (callback != NULL) 181 if (callback != NULL) {
191 sci_remote_node_context_save_cbparams( 182 sci_rnc->user_callback = callback;
192 sci_rnc, callback, callback_parameter); 183 sci_rnc->user_cookie = callback_parameter;
184 }
193 } 185 }
194} 186}
195 187
@@ -610,7 +602,8 @@ enum sci_status sci_remote_node_context_suspend(
610 * entry into the SCI_RNC_READY state that a suspension 602 * entry into the SCI_RNC_READY state that a suspension
611 * needs to be done immediately. 603 * needs to be done immediately.
612 */ 604 */
613 sci_rnc->destination_state = RNC_DEST_SUSPENDED; 605 if (sci_rnc->destination_state != RNC_DEST_FINAL)
606 sci_rnc->destination_state = RNC_DEST_SUSPENDED;
614 sci_rnc->suspend_type = suspend_type; 607 sci_rnc->suspend_type = suspend_type;
615 sci_rnc->suspend_reason = suspend_reason; 608 sci_rnc->suspend_reason = suspend_reason;
616 return SCI_SUCCESS; 609 return SCI_SUCCESS;
@@ -680,12 +673,9 @@ enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *s
680 if (sci_rnc->remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX) 673 if (sci_rnc->remote_node_index == SCIC_SDS_REMOTE_NODE_CONTEXT_INVALID_INDEX)
681 return SCI_FAILURE_INVALID_STATE; 674 return SCI_FAILURE_INVALID_STATE;
682 675
683 if (test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) 676 sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn, cb_p,
684 sci_remote_node_context_save_cbparams(sci_rnc, cb_fn, 677 RNC_DEST_READY);
685 cb_p); 678 if (!test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) {
686 else {
687 sci_remote_node_context_setup_to_resume(sci_rnc, cb_fn,
688 cb_p, RNC_DEST_READY);
689 sci_remote_node_context_construct_buffer(sci_rnc); 679 sci_remote_node_context_construct_buffer(sci_rnc);
690 sci_change_state(&sci_rnc->sm, SCI_RNC_POSTING); 680 sci_change_state(&sci_rnc->sm, SCI_RNC_POSTING);
691 } 681 }
@@ -694,38 +684,30 @@ enum sci_status sci_remote_node_context_resume(struct sci_remote_node_context *s
694 case SCI_RNC_POSTING: 684 case SCI_RNC_POSTING:
695 case SCI_RNC_INVALIDATING: 685 case SCI_RNC_INVALIDATING:
696 case SCI_RNC_RESUMING: 686 case SCI_RNC_RESUMING:
697 if (test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) 687 /* We are still waiting to post when a resume was
698 sci_remote_node_context_save_cbparams(sci_rnc, cb_fn, 688 * requested.
699 cb_p); 689 */
700 else { 690 switch (sci_rnc->destination_state) {
701 /* We are still waiting to post when a resume was 691 case RNC_DEST_SUSPENDED:
702 * requested. 692 case RNC_DEST_SUSPENDED_RESUME:
693 /* Previously waiting to suspend after posting.
694 * Now continue onto resumption.
703 */ 695 */
704 switch (sci_rnc->destination_state) { 696 sci_remote_node_context_setup_to_resume(
705 case RNC_DEST_SUSPENDED: 697 sci_rnc, cb_fn, cb_p,
706 case RNC_DEST_SUSPENDED_RESUME: 698 RNC_DEST_SUSPENDED_RESUME);
707 /* Previously waiting to suspend after posting. 699 break;
708 * Now continue onto resumption. 700 default:
709 */ 701 sci_remote_node_context_setup_to_resume(
710 sci_remote_node_context_setup_to_resume( 702 sci_rnc, cb_fn, cb_p,
711 sci_rnc, cb_fn, cb_p, 703 RNC_DEST_READY);
712 RNC_DEST_SUSPENDED_RESUME); 704 break;
713 break;
714 default:
715 sci_remote_node_context_setup_to_resume(
716 sci_rnc, cb_fn, cb_p,
717 RNC_DEST_READY);
718 break;
719 }
720 } 705 }
721 return SCI_SUCCESS; 706 return SCI_SUCCESS;
722 707
723 case SCI_RNC_TX_SUSPENDED: 708 case SCI_RNC_TX_SUSPENDED:
724 case SCI_RNC_TX_RX_SUSPENDED: 709 case SCI_RNC_TX_RX_SUSPENDED:
725 if (test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) 710 {
726 sci_remote_node_context_save_cbparams(sci_rnc, cb_fn,
727 cb_p);
728 else {
729 struct domain_device *dev = idev->domain_dev; 711 struct domain_device *dev = idev->domain_dev;
730 /* If this is an expander attached SATA device we must 712 /* If this is an expander attached SATA device we must
731 * invalidate and repost the RNC since this is the only 713 * 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 sci_remote_node_context_setup_to_resume( 717 sci_remote_node_context_setup_to_resume(
736 sci_rnc, cb_fn, cb_p, RNC_DEST_READY); 718 sci_rnc, cb_fn, cb_p, RNC_DEST_READY);
737 719
738 if (dev_is_sata(dev) && dev->parent) 720 if (!test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) {
739 sci_change_state(&sci_rnc->sm, 721 if ((dev_is_sata(dev) && dev->parent) ||
740 SCI_RNC_INVALIDATING); 722 (sci_rnc->destination_state == RNC_DEST_FINAL))
741 else 723 sci_change_state(&sci_rnc->sm,
742 sci_change_state(&sci_rnc->sm, 724 SCI_RNC_INVALIDATING);
743 SCI_RNC_RESUMING); 725 else
726 sci_change_state(&sci_rnc->sm,
727 SCI_RNC_RESUMING);
728 }
744 } 729 }
745 return SCI_SUCCESS; 730 return SCI_SUCCESS;
746 731
747 case SCI_RNC_AWAIT_SUSPENSION: 732 case SCI_RNC_AWAIT_SUSPENSION:
748 if (test_bit(IDEV_ABORT_PATH_ACTIVE, &idev->flags)) 733 sci_remote_node_context_setup_to_resume(
749 sci_remote_node_context_save_cbparams(sci_rnc, cb_fn, 734 sci_rnc, cb_fn, cb_p, RNC_DEST_SUSPENDED_RESUME);
750 cb_p);
751 else
752 sci_remote_node_context_setup_to_resume(
753 sci_rnc, cb_fn, cb_p,
754 RNC_DEST_SUSPENDED_RESUME);
755 return SCI_SUCCESS; 735 return SCI_SUCCESS;
756 default: 736 default:
757 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)), 737 dev_warn(scirdev_to_dev(rnc_to_dev(sci_rnc)),