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