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

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxx>
---
 drivers/scsi/qedi/qedi_fw.c | 57 ++++++++++++++++++++++++---------------------
 1 file changed, 31 insertions(+), 26 deletions(-)

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;
-- 
1.8.3.1




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]

  Powered by Linux