aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/isci/task.c
diff options
context:
space:
mode:
authorJeff Skirvin <jeffrey.d.skirvin@intel.com>2012-03-09 01:41:51 -0500
committerDan Williams <dan.j.williams@intel.com>2012-05-17 17:33:37 -0400
commit5b6bf225e7fc249c703e19bf2c983d1a59178874 (patch)
tree9c9b855474b77323c0d89b33ac224e0c1f016c73 /drivers/scsi/isci/task.c
parent726980d56908f2e230624394f03743689db3110c (diff)
isci: Manage device suspensions during TC terminations.
TCs must be terminated only while the RNC is suspended. This commit adds remote device suspensions and resumptions in the abort, reset and termination paths. 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/task.c')
-rw-r--r--drivers/scsi/isci/task.c80
1 files changed, 48 insertions, 32 deletions
diff --git a/drivers/scsi/isci/task.c b/drivers/scsi/isci/task.c
index 374254ede9d4..9b8632f33dd9 100644
--- a/drivers/scsi/isci/task.c
+++ b/drivers/scsi/isci/task.c
@@ -716,6 +716,8 @@ void isci_terminate_pending_requests(struct isci_host *ihost,
716 unsigned long flags; 716 unsigned long flags;
717 LIST_HEAD(list); 717 LIST_HEAD(list);
718 718
719 isci_remote_device_suspend(ihost, idev);
720
719 spin_lock_irqsave(&ihost->scic_lock, flags); 721 spin_lock_irqsave(&ihost->scic_lock, flags);
720 list_splice_init(&idev->reqs_in_process, &list); 722 list_splice_init(&idev->reqs_in_process, &list);
721 723
@@ -826,40 +828,47 @@ static int isci_task_send_lu_reset_sas(
826 828
827int isci_task_lu_reset(struct domain_device *dev, u8 *lun) 829int isci_task_lu_reset(struct domain_device *dev, u8 *lun)
828{ 830{
829 struct isci_host *isci_host = dev_to_ihost(dev); 831 struct isci_host *ihost = dev_to_ihost(dev);
830 struct isci_remote_device *isci_device; 832 struct isci_remote_device *isci_device;
831 unsigned long flags; 833 unsigned long flags;
832 int ret; 834 int ret;
833 835
834 spin_lock_irqsave(&isci_host->scic_lock, flags); 836 spin_lock_irqsave(&ihost->scic_lock, flags);
835 isci_device = isci_lookup_device(dev); 837 isci_device = isci_lookup_device(dev);
836 spin_unlock_irqrestore(&isci_host->scic_lock, flags); 838 spin_unlock_irqrestore(&ihost->scic_lock, flags);
837 839
838 dev_dbg(&isci_host->pdev->dev, 840 dev_dbg(&ihost->pdev->dev,
839 "%s: domain_device=%p, isci_host=%p; isci_device=%p\n", 841 "%s: domain_device=%p, isci_host=%p; isci_device=%p\n",
840 __func__, dev, isci_host, isci_device); 842 __func__, dev, ihost, isci_device);
841 843
842 if (!isci_device) { 844 if (!isci_device) {
843 /* If the device is gone, stop the escalations. */ 845 /* If the device is gone, stop the escalations. */
844 dev_dbg(&isci_host->pdev->dev, "%s: No dev\n", __func__); 846 dev_dbg(&ihost->pdev->dev, "%s: No dev\n", __func__);
845 847
846 ret = TMF_RESP_FUNC_COMPLETE; 848 ret = TMF_RESP_FUNC_COMPLETE;
847 goto out; 849 goto out;
848 } 850 }
851 if (isci_remote_device_suspend(ihost, isci_device) != SCI_SUCCESS) {
852 dev_dbg(&ihost->pdev->dev,
853 "%s: device = %p; failed to suspend\n",
854 __func__, isci_device);
855 ret = TMF_RESP_FUNC_FAILED;
856 goto out;
857 }
849 858
850 /* Send the task management part of the reset. */ 859 /* Send the task management part of the reset. */
851 if (dev_is_sata(dev)) { 860 if (dev_is_sata(dev)) {
852 sas_ata_schedule_reset(dev); 861 sas_ata_schedule_reset(dev);
853 ret = TMF_RESP_FUNC_COMPLETE; 862 ret = TMF_RESP_FUNC_COMPLETE;
854 } else 863 } else
855 ret = isci_task_send_lu_reset_sas(isci_host, isci_device, lun); 864 ret = isci_task_send_lu_reset_sas(ihost, isci_device, lun);
856 865
857 /* If the LUN reset worked, all the I/O can now be terminated. */ 866 /* If the LUN reset worked, all the I/O can now be terminated. */
858 if (ret == TMF_RESP_FUNC_COMPLETE) 867 if (ret == TMF_RESP_FUNC_COMPLETE) {
859 /* Terminate all I/O now. */ 868 /* Terminate all I/O now. */
860 isci_terminate_pending_requests(isci_host, 869 isci_terminate_pending_requests(ihost, isci_device);
861 isci_device); 870 isci_remote_device_resume(ihost, isci_device, NULL, NULL);
862 871 }
863 out: 872 out:
864 isci_put_device(isci_device); 873 isci_put_device(isci_device);
865 return ret; 874 return ret;
@@ -976,7 +985,7 @@ int isci_task_abort_task(struct sas_task *task)
976 spin_unlock(&task->task_state_lock); 985 spin_unlock(&task->task_state_lock);
977 spin_unlock_irqrestore(&isci_host->scic_lock, flags); 986 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
978 987
979 dev_dbg(&isci_host->pdev->dev, 988 dev_warn(&isci_host->pdev->dev,
980 "%s: dev = %p, task = %p, old_request == %p\n", 989 "%s: dev = %p, task = %p, old_request == %p\n",
981 __func__, isci_device, task, old_request); 990 __func__, isci_device, task, old_request);
982 991
@@ -998,7 +1007,7 @@ int isci_task_abort_task(struct sas_task *task)
998 1007
999 ret = TMF_RESP_FUNC_COMPLETE; 1008 ret = TMF_RESP_FUNC_COMPLETE;
1000 1009
1001 dev_dbg(&isci_host->pdev->dev, 1010 dev_warn(&isci_host->pdev->dev,
1002 "%s: abort task not needed for %p\n", 1011 "%s: abort task not needed for %p\n",
1003 __func__, task); 1012 __func__, task);
1004 goto out; 1013 goto out;
@@ -1022,7 +1031,7 @@ int isci_task_abort_task(struct sas_task *task)
1022 /* The request was already being handled by someone else (because 1031 /* The request was already being handled by someone else (because
1023 * they got to set the state away from started). 1032 * they got to set the state away from started).
1024 */ 1033 */
1025 dev_dbg(&isci_host->pdev->dev, 1034 dev_warn(&isci_host->pdev->dev,
1026 "%s: device = %p; old_request %p already being aborted\n", 1035 "%s: device = %p; old_request %p already being aborted\n",
1027 __func__, 1036 __func__,
1028 isci_device, old_request); 1037 isci_device, old_request);
@@ -1035,7 +1044,7 @@ int isci_task_abort_task(struct sas_task *task)
1035 1044
1036 spin_unlock_irqrestore(&isci_host->scic_lock, flags); 1045 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
1037 1046
1038 dev_dbg(&isci_host->pdev->dev, 1047 dev_warn(&isci_host->pdev->dev,
1039 "%s: %s request" 1048 "%s: %s request"
1040 " or complete_in_target (%d), thus no TMF\n", 1049 " or complete_in_target (%d), thus no TMF\n",
1041 __func__, 1050 __func__,
@@ -1068,6 +1077,15 @@ int isci_task_abort_task(struct sas_task *task)
1068 */ 1077 */
1069 perform_termination = 1; 1078 perform_termination = 1;
1070 1079
1080 if (isci_device && !test_bit(IDEV_GONE, &isci_device->flags) &&
1081 (isci_remote_device_suspend(isci_host, isci_device)
1082 != SCI_SUCCESS)) {
1083 dev_warn(&isci_host->pdev->dev,
1084 "%s: device = %p; failed to suspend\n",
1085 __func__, isci_device);
1086 goto out;
1087 }
1088
1071 } else { 1089 } else {
1072 /* Fill in the tmf stucture */ 1090 /* Fill in the tmf stucture */
1073 isci_task_build_abort_task_tmf(&tmf, isci_tmf_ssp_task_abort, 1091 isci_task_build_abort_task_tmf(&tmf, isci_tmf_ssp_task_abort,
@@ -1076,6 +1094,14 @@ int isci_task_abort_task(struct sas_task *task)
1076 1094
1077 spin_unlock_irqrestore(&isci_host->scic_lock, flags); 1095 spin_unlock_irqrestore(&isci_host->scic_lock, flags);
1078 1096
1097 if (isci_remote_device_suspend(isci_host, isci_device)
1098 != SCI_SUCCESS) {
1099 dev_warn(&isci_host->pdev->dev,
1100 "%s: device = %p; failed to suspend\n",
1101 __func__, isci_device);
1102 goto out;
1103 }
1104
1079 #define ISCI_ABORT_TASK_TIMEOUT_MS 500 /* 1/2 second timeout */ 1105 #define ISCI_ABORT_TASK_TIMEOUT_MS 500 /* 1/2 second timeout */
1080 ret = isci_task_execute_tmf(isci_host, isci_device, &tmf, 1106 ret = isci_task_execute_tmf(isci_host, isci_device, &tmf,
1081 ISCI_ABORT_TASK_TIMEOUT_MS); 1107 ISCI_ABORT_TASK_TIMEOUT_MS);
@@ -1083,7 +1109,7 @@ int isci_task_abort_task(struct sas_task *task)
1083 if (ret == TMF_RESP_FUNC_COMPLETE) 1109 if (ret == TMF_RESP_FUNC_COMPLETE)
1084 perform_termination = 1; 1110 perform_termination = 1;
1085 else 1111 else
1086 dev_dbg(&isci_host->pdev->dev, 1112 dev_warn(&isci_host->pdev->dev,
1087 "%s: isci_task_send_tmf failed\n", __func__); 1113 "%s: isci_task_send_tmf failed\n", __func__);
1088 } 1114 }
1089 if (perform_termination) { 1115 if (perform_termination) {
@@ -1094,6 +1120,7 @@ int isci_task_abort_task(struct sas_task *task)
1094 */ 1120 */
1095 isci_terminate_request_core(isci_host, isci_device, 1121 isci_terminate_request_core(isci_host, isci_device,
1096 old_request); 1122 old_request);
1123 isci_remote_device_resume(isci_host, isci_device, NULL, NULL);
1097 } 1124 }
1098 1125
1099 /* Make sure we do not leave a reference to aborted_io_completion */ 1126 /* Make sure we do not leave a reference to aborted_io_completion */
@@ -1251,21 +1278,13 @@ static int isci_reset_device(struct isci_host *ihost,
1251 struct isci_remote_device *idev) 1278 struct isci_remote_device *idev)
1252{ 1279{
1253 int rc; 1280 int rc;
1254 unsigned long flags;
1255 enum sci_status status; 1281 enum sci_status status;
1256 struct sas_phy *phy = sas_get_local_phy(dev); 1282 struct sas_phy *phy = sas_get_local_phy(dev);
1257 struct isci_port *iport = dev->port->lldd_port; 1283 struct isci_port *iport = dev->port->lldd_port;
1258 1284
1259 dev_dbg(&ihost->pdev->dev, "%s: idev %p\n", __func__, idev); 1285 dev_dbg(&ihost->pdev->dev, "%s: idev %p\n", __func__, idev);
1260 1286
1261 spin_lock_irqsave(&ihost->scic_lock, flags); 1287 if (isci_remote_device_reset(ihost, idev) != SCI_SUCCESS) {
1262 status = sci_remote_device_reset(idev);
1263 spin_unlock_irqrestore(&ihost->scic_lock, flags);
1264
1265 if (status != SCI_SUCCESS) {
1266 dev_dbg(&ihost->pdev->dev,
1267 "%s: sci_remote_device_reset(%p) returned %d!\n",
1268 __func__, idev, status);
1269 rc = TMF_RESP_FUNC_FAILED; 1288 rc = TMF_RESP_FUNC_FAILED;
1270 goto out; 1289 goto out;
1271 } 1290 }
@@ -1281,15 +1300,12 @@ static int isci_reset_device(struct isci_host *ihost,
1281 isci_remote_device_nuke_requests(ihost, idev); 1300 isci_remote_device_nuke_requests(ihost, idev);
1282 1301
1283 /* Since all pending TCs have been cleaned, resume the RNC. */ 1302 /* Since all pending TCs have been cleaned, resume the RNC. */
1284 spin_lock_irqsave(&ihost->scic_lock, flags); 1303 status = isci_remote_device_reset_complete(ihost, idev);
1285 status = sci_remote_device_reset_complete(idev);
1286 spin_unlock_irqrestore(&ihost->scic_lock, flags);
1287 1304
1288 if (status != SCI_SUCCESS) { 1305 if (status != SCI_SUCCESS)
1289 dev_dbg(&ihost->pdev->dev, 1306 dev_dbg(&ihost->pdev->dev,
1290 "%s: sci_remote_device_reset_complete(%p) " 1307 "%s: isci_remote_device_reset_complete(%p) "
1291 "returned %d!\n", __func__, idev, status); 1308 "returned %d!\n", __func__, idev, status);
1292 }
1293 1309
1294 dev_dbg(&ihost->pdev->dev, "%s: idev %p complete.\n", __func__, idev); 1310 dev_dbg(&ihost->pdev->dev, "%s: idev %p complete.\n", __func__, idev);
1295 out: 1311 out:
@@ -1305,7 +1321,7 @@ int isci_task_I_T_nexus_reset(struct domain_device *dev)
1305 int ret; 1321 int ret;
1306 1322
1307 spin_lock_irqsave(&ihost->scic_lock, flags); 1323 spin_lock_irqsave(&ihost->scic_lock, flags);
1308 idev = isci_lookup_device(dev); 1324 idev = isci_get_device(dev);
1309 spin_unlock_irqrestore(&ihost->scic_lock, flags); 1325 spin_unlock_irqrestore(&ihost->scic_lock, flags);
1310 1326
1311 if (!idev) { 1327 if (!idev) {