diff mbox series

[18/22] qedi: prep driver for switch to blk tags

Message ID 1608187332-4434-19-git-send-email-michael.christie@oracle.com
State New
Headers show
Series iscsi: lock clean ups | expand

Commit Message

Mike Christie Dec. 17, 2020, 6:42 a.m. UTC
We currently implement our own tagging which just adds another
layer of locks. For scsi cmds we can just use the block layer
tags. This patch preps qedi for this change by:

1. Having it use the correct itt to task look up function.
See below for info and question.

2. Using iscsi_complete_scsi_task when it has access to the task
instead of playing tricks with the itt which may not work with
multiple queues.

Question for Manish:

We are supposed to use iscsi_itt_to_ctask for scsi tasks and
iscsi_itt_to_task for iscsi "mgmt" tasks. The latter are nops,
login, logout, etc.

I could not tell if the !found cases in
qedi_process_cmd_cleanup_resp were for scsi cmds or mgmt ones.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/qedi/qedi_fw.c | 57 ++++++++++++++++++++++++---------------------
 1 file changed, 31 insertions(+), 26 deletions(-)
diff mbox series

Patch

diff --git a/drivers/scsi/qedi/qedi_fw.c b/drivers/scsi/qedi/qedi_fw.c
index 440ddd2..d93a6b2 100644
--- a/drivers/scsi/qedi/qedi_fw.c
+++ b/drivers/scsi/qedi/qedi_fw.c
@@ -627,20 +627,15 @@  static void qedi_scsi_completion(struct qedi_ctx *qedi,
 
 	qedi_iscsi_unmap_sg_list(cmd);
 
-	hdr = (struct iscsi_scsi_rsp *)task->hdr;
-	hdr->opcode = cqe_data_in->opcode;
-	hdr->max_cmdsn = cpu_to_be32(cqe_data_in->max_cmd_sn);
-	hdr->exp_cmdsn = cpu_to_be32(cqe_data_in->exp_cmd_sn);
-	hdr->itt = build_itt(cqe->cqe_solicited.itid, conn->session->age);
-	hdr->response = cqe_data_in->reserved1;
-	hdr->cmd_status = cqe_data_in->status_rsvd;
-	hdr->flags = cqe_data_in->flags;
-	hdr->residual_count = cpu_to_be32(cqe_data_in->residual_count);
-
-	if (hdr->cmd_status == SAM_STAT_CHECK_CONDITION) {
+	sc_cmd->result = (DID_OK << 16) | cqe_data_in->status_rsvd;
+	if (cqe_data_in->reserved1 != ISCSI_STATUS_CMD_COMPLETED)
+		sc_cmd->result = DID_ERROR << 16;
+
+	if (cqe_data_in->status_rsvd == SAM_STAT_CHECK_CONDITION) {
 		datalen = cqe_data_in->reserved2 &
 			  ISCSI_COMMON_HDR_DATA_SEG_LEN_MASK;
-		memcpy((char *)conn->data, (char *)cmd->sense_buffer, datalen);
+		memcpy(sc_cmd->sense_buffer, cmd->sense_buffer,
+		       min(datalen, SCSI_SENSE_BUFFERSIZE));
 	}
 
 	/* If f/w reports data underrun err then set residual to IO transfer
@@ -653,9 +648,23 @@  static void qedi_scsi_completion(struct qedi_ctx *qedi,
 			  hdr->itt, cqe_data_in->flags, cmd->task_id,
 			  qedi_conn->iscsi_conn_id, hdr->residual_count,
 			  scsi_bufflen(sc_cmd));
-		hdr->residual_count = cpu_to_be32(scsi_bufflen(sc_cmd));
-		hdr->flags |= ISCSI_FLAG_CMD_UNDERFLOW;
-		hdr->flags &= (~ISCSI_FLAG_CMD_OVERFLOW);
+
+		cqe_data_in->residual_count = scsi_bufflen(sc_cmd);
+		cqe_data_in->flags |= ISCSI_FLAG_CMD_UNDERFLOW;
+		cqe_data_in->flags &= (~ISCSI_FLAG_CMD_OVERFLOW);
+	}
+
+	if (cqe_data_in->flags & (ISCSI_FLAG_CMD_UNDERFLOW |
+				  ISCSI_FLAG_CMD_OVERFLOW)) {
+		int res_count = cqe_data_in->residual_count;
+
+		if (res_count > 0 &&
+		    (cqe_data_in->flags & ISCSI_FLAG_CMD_OVERFLOW ||
+		    res_count <= scsi_bufflen(sc_cmd)))
+			scsi_set_resid(sc_cmd, res_count);
+		else
+			sc_cmd->result = (DID_BAD_TARGET << 16) |
+						cqe_data_in->status_rsvd;
 	}
 
 	spin_lock(&qedi_conn->list_lock);
@@ -674,8 +683,8 @@  static void qedi_scsi_completion(struct qedi_ctx *qedi,
 		qedi_trace_io(qedi, task, cmd->task_id, QEDI_IO_TRACE_RSP);
 
 	qedi_clear_task_idx(qedi, cmd->task_id);
-	__iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr,
-			     conn->data, datalen);
+	iscsi_complete_scsi_task(task, cqe_data_in->exp_cmd_sn,
+				 cqe_data_in->max_cmd_sn);
 error:
 	spin_unlock_bh(&session->back_lock);
 }
@@ -796,11 +805,7 @@  static void qedi_process_cmd_cleanup_resp(struct qedi_ctx *qedi,
 		if ((tmf_hdr->flags & ISCSI_FLAG_TM_FUNC_MASK) ==
 		    ISCSI_TM_FUNC_ABORT_TASK) {
 			spin_lock_bh(&conn->session->back_lock);
-
-			protoitt = build_itt(get_itt(tmf_hdr->rtt),
-					     conn->session->age);
-			task = iscsi_itt_to_task(conn, protoitt);
-
+			task = iscsi_itt_to_ctask(conn, tmf_hdr->rtt);
 			spin_unlock_bh(&conn->session->back_lock);
 
 			if (!task) {
@@ -1387,8 +1392,8 @@  static void qedi_tmf_work(struct work_struct *work)
 	tmf_hdr = (struct iscsi_tm *)mtask->hdr;
 	set_bit(QEDI_CONN_FW_CLEANUP, &qedi_conn->flags);
 
-	ctask = iscsi_itt_to_task(conn, tmf_hdr->rtt);
-	if (!ctask || !ctask->sc) {
+	ctask = iscsi_itt_to_ctask(conn, tmf_hdr->rtt);
+	if (!ctask) {
 		QEDI_ERR(&qedi->dbg_ctx, "Task already completed\n");
 		goto abort_ret;
 	}
@@ -1520,8 +1525,8 @@  static int qedi_send_iscsi_tmf(struct qedi_conn *qedi_conn,
 
 	if ((tmf_hdr->flags & ISCSI_FLAG_TM_FUNC_MASK) ==
 	     ISCSI_TM_FUNC_ABORT_TASK) {
-		ctask = iscsi_itt_to_task(conn, tmf_hdr->rtt);
-		if (!ctask || !ctask->sc) {
+		ctask = iscsi_itt_to_ctask(conn, tmf_hdr->rtt);
+		if (!ctask) {
 			QEDI_ERR(&qedi->dbg_ctx,
 				 "Could not get reference task\n");
 			return 0;