[PATCH 04/18] qla2xxx: Proper cleanup of pass through commands when firmware returns error.

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

 



From: Giridhar Malavali <giridhar.malavali@xxxxxxxxxx>

Signed-off-by: Giridhar Malavali <giridhar.malavali@xxxxxxxxxx>
Signed-off-by: Chad Dupuis <chad.dupuis@xxxxxxxxxx>
---
 drivers/scsi/qla2xxx/qla_isr.c |   73 ++++++++++++++++++++++++++++-----------
 drivers/scsi/qla2xxx/qla_os.c  |   19 +++++-----
 2 files changed, 61 insertions(+), 31 deletions(-)

diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index b6023e9..c5d6cd1 100644
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -1895,6 +1895,45 @@ qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt)
 	}
 }
 
+static int
+qla2x00_free_sp_ctx(scsi_qla_host_t *vha, srb_t *sp)
+{
+	struct qla_hw_data *ha = vha->hw;
+	struct srb_ctx *ctx;
+
+	if (!sp->ctx)
+		return 1;
+
+	ctx = sp->ctx;
+
+	if (ctx->type == SRB_LOGIN_CMD ||
+	    ctx->type == SRB_LOGOUT_CMD ||
+	    ctx->type == SRB_TM_CMD) {
+		((struct srb_iocb*)ctx->u.iocb_cmd)->done(sp);
+		return 0;
+	} else if (ctx->type == SRB_ADISC_CMD) {
+		((struct srb_iocb*)ctx->u.iocb_cmd)->free(sp);
+		return 0;
+	} else {
+		struct fc_bsg_job *bsg_job;
+
+		bsg_job = ctx->u.bsg_job;
+		if (ctx->type == SRB_ELS_CMD_HST ||
+		    ctx->type == SRB_CT_CMD)
+			kfree(sp->fcport);
+
+		bsg_job->reply->reply_data.ctels_reply.status =
+		    FC_CTELS_STATUS_OK;
+		bsg_job->reply->result = DID_ERROR << 16;
+		bsg_job->reply->reply_payload_rcv_len = 0;
+		kfree(sp->ctx);
+		mempool_free(sp, ha->srb_mempool);
+		bsg_job->job_done(bsg_job);
+		return 0;
+	}
+	return 1;
+}
+
 /**
  * qla2x00_error_entry() - Process an error entry.
  * @ha: SCSI driver HA context
@@ -1905,7 +1944,7 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt)
 {
 	srb_t *sp;
 	struct qla_hw_data *ha = vha->hw;
-	uint32_t handle = LSW(pkt->handle);
+	const char func[] = "ERROR-IOCB";
 	uint16_t que = MSW(pkt->handle);
 	struct req_que *req = ha->req_q_map[que];
 
@@ -1928,28 +1967,20 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt)
 		ql_dbg(ql_dbg_async, vha, 0x502f,
 		    "UNKNOWN flag error.\n");
 
-	/* Validate handle. */
-	if (handle < MAX_OUTSTANDING_COMMANDS)
-		sp = req->outstanding_cmds[handle];
-	else
-		sp = NULL;
-
+	sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
 	if (sp) {
-		/* Free outstanding command slot. */
-		req->outstanding_cmds[handle] = NULL;
-
-		/* Bad payload or header */
-		if (pkt->entry_status &
-		    (RF_INV_E_ORDER | RF_INV_E_COUNT |
-		     RF_INV_E_PARAM | RF_INV_E_TYPE)) {
-			sp->cmd->result = DID_ERROR << 16;
-		} else if (pkt->entry_status & RF_BUSY) {
-			sp->cmd->result = DID_BUS_BUSY << 16;
-		} else {
-			sp->cmd->result = DID_ERROR << 16;
+		if (qla2x00_free_sp_ctx (vha, sp)) {
+			if (pkt->entry_status &
+			    (RF_INV_E_ORDER | RF_INV_E_COUNT |
+			     RF_INV_E_PARAM | RF_INV_E_TYPE)) {
+				sp->cmd->result = DID_ERROR << 16;
+			} else if (pkt->entry_status & RF_BUSY) {
+				sp->cmd->result = DID_BUS_BUSY << 16;
+			} else {
+				sp->cmd->result = DID_ERROR << 16;
+			}
+			qla2x00_sp_compl(ha, sp);
 		}
-		qla2x00_sp_compl(ha, sp);
-
 	} else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type ==
 		COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7
 		|| pkt->entry_type == COMMAND_TYPE_6) {
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index ae1699f..c9a7452 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -3690,16 +3690,6 @@ qla2x00_sp_free_dma(srb_t *sp)
 		sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
 	}
 
-	CMD_SP(cmd) = NULL;
-}
-
-static void
-qla2x00_sp_final_compl(struct qla_hw_data *ha, srb_t *sp)
-{
-	struct scsi_cmnd *cmd = sp->cmd;
-
-	qla2x00_sp_free_dma(sp);
-
 	if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
 		struct ct6_dsd *ctx = sp->ctx;
 		dma_pool_free(ha->fcp_cmnd_dma_pool, ctx->fcp_cmnd,
@@ -3711,6 +3701,15 @@ qla2x00_sp_final_compl(struct qla_hw_data *ha, srb_t *sp)
 		sp->ctx = NULL;
 	}
 
+	CMD_SP(cmd) = NULL;
+}
+
+static void
+qla2x00_sp_final_compl(struct qla_hw_data *ha, srb_t *sp)
+{
+	struct scsi_cmnd *cmd = sp->cmd;
+
+	qla2x00_sp_free_dma(sp);
 	mempool_free(sp, ha->srb_mempool);
 	cmd->scsi_done(cmd);
 }
-- 
1.6.0.2


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[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