aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/nvme/host/fc.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/drivers/nvme/host/fc.c b/drivers/nvme/host/fc.c
index 5b14cbefb724..2edae54688e8 100644
--- a/drivers/nvme/host/fc.c
+++ b/drivers/nvme/host/fc.c
@@ -1139,6 +1139,7 @@ nvme_fc_xmt_disconnect_assoc(struct nvme_fc_ctrl *ctrl)
1139/* *********************** NVME Ctrl Routines **************************** */ 1139/* *********************** NVME Ctrl Routines **************************** */
1140 1140
1141static void __nvme_fc_final_op_cleanup(struct request *rq); 1141static void __nvme_fc_final_op_cleanup(struct request *rq);
1142static void nvme_fc_error_recovery(struct nvme_fc_ctrl *ctrl, char *errmsg);
1142 1143
1143static int 1144static int
1144nvme_fc_reinit_request(void *data, struct request *rq) 1145nvme_fc_reinit_request(void *data, struct request *rq)
@@ -1265,7 +1266,7 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req)
1265 struct nvme_command *sqe = &op->cmd_iu.sqe; 1266 struct nvme_command *sqe = &op->cmd_iu.sqe;
1266 __le16 status = cpu_to_le16(NVME_SC_SUCCESS << 1); 1267 __le16 status = cpu_to_le16(NVME_SC_SUCCESS << 1);
1267 union nvme_result result; 1268 union nvme_result result;
1268 bool complete_rq; 1269 bool complete_rq, terminate_assoc = true;
1269 1270
1270 /* 1271 /*
1271 * WARNING: 1272 * WARNING:
@@ -1294,6 +1295,14 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req)
1294 * fabricate a CQE, the following fields will not be set as they 1295 * fabricate a CQE, the following fields will not be set as they
1295 * are not referenced: 1296 * are not referenced:
1296 * cqe.sqid, cqe.sqhd, cqe.command_id 1297 * cqe.sqid, cqe.sqhd, cqe.command_id
1298 *
1299 * Failure or error of an individual i/o, in a transport
1300 * detected fashion unrelated to the nvme completion status,
1301 * potentially cause the initiator and target sides to get out
1302 * of sync on SQ head/tail (aka outstanding io count allowed).
1303 * Per FC-NVME spec, failure of an individual command requires
1304 * the connection to be terminated, which in turn requires the
1305 * association to be terminated.
1297 */ 1306 */
1298 1307
1299 fc_dma_sync_single_for_cpu(ctrl->lport->dev, op->fcp_req.rspdma, 1308 fc_dma_sync_single_for_cpu(ctrl->lport->dev, op->fcp_req.rspdma,
@@ -1359,6 +1368,8 @@ nvme_fc_fcpio_done(struct nvmefc_fcp_req *req)
1359 goto done; 1368 goto done;
1360 } 1369 }
1361 1370
1371 terminate_assoc = false;
1372
1362done: 1373done:
1363 if (op->flags & FCOP_FLAGS_AEN) { 1374 if (op->flags & FCOP_FLAGS_AEN) {
1364 nvme_complete_async_event(&queue->ctrl->ctrl, status, &result); 1375 nvme_complete_async_event(&queue->ctrl->ctrl, status, &result);
@@ -1366,7 +1377,7 @@ done:
1366 atomic_set(&op->state, FCPOP_STATE_IDLE); 1377 atomic_set(&op->state, FCPOP_STATE_IDLE);
1367 op->flags = FCOP_FLAGS_AEN; /* clear other flags */ 1378 op->flags = FCOP_FLAGS_AEN; /* clear other flags */
1368 nvme_fc_ctrl_put(ctrl); 1379 nvme_fc_ctrl_put(ctrl);
1369 return; 1380 goto check_error;
1370 } 1381 }
1371 1382
1372 complete_rq = __nvme_fc_fcpop_chk_teardowns(ctrl, op); 1383 complete_rq = __nvme_fc_fcpop_chk_teardowns(ctrl, op);
@@ -1379,6 +1390,10 @@ done:
1379 nvme_end_request(rq, status, result); 1390 nvme_end_request(rq, status, result);
1380 } else 1391 } else
1381 __nvme_fc_final_op_cleanup(rq); 1392 __nvme_fc_final_op_cleanup(rq);
1393
1394check_error:
1395 if (terminate_assoc)
1396 nvme_fc_error_recovery(ctrl, "transport detected io error");
1382} 1397}
1383 1398
1384static int 1399static int