Commit c4631191 authored by Giridhar Malavali's avatar Giridhar Malavali Committed by James Bottomley

[SCSI] qla2xxx: Proper cleanup of pass through commands when firmware returns error.

[jejb: fixed up checkpatch and casting errors]
Signed-off-by: default avatarGiridhar Malavali <giridhar.malavali@qlogic.com>
Signed-off-by: default avatarChad Dupuis <chad.dupuis@qlogic.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent cfb0919c
...@@ -1895,6 +1895,45 @@ qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt) ...@@ -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) {
ctx->u.iocb_cmd->done(sp);
return 0;
} else if (ctx->type == SRB_ADISC_CMD) {
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. * qla2x00_error_entry() - Process an error entry.
* @ha: SCSI driver HA context * @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) ...@@ -1905,7 +1944,7 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt)
{ {
srb_t *sp; srb_t *sp;
struct qla_hw_data *ha = vha->hw; struct qla_hw_data *ha = vha->hw;
uint32_t handle = LSW(pkt->handle); const char func[] = "ERROR-IOCB";
uint16_t que = MSW(pkt->handle); uint16_t que = MSW(pkt->handle);
struct req_que *req = ha->req_q_map[que]; 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) ...@@ -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, ql_dbg(ql_dbg_async, vha, 0x502f,
"UNKNOWN flag error.\n"); "UNKNOWN flag error.\n");
/* Validate handle. */ sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
if (handle < MAX_OUTSTANDING_COMMANDS)
sp = req->outstanding_cmds[handle];
else
sp = NULL;
if (sp) { if (sp) {
/* Free outstanding command slot. */ if (qla2x00_free_sp_ctx(vha, sp)) {
req->outstanding_cmds[handle] = NULL; if (pkt->entry_status &
(RF_INV_E_ORDER | RF_INV_E_COUNT |
/* Bad payload or header */ RF_INV_E_PARAM | RF_INV_E_TYPE)) {
if (pkt->entry_status & sp->cmd->result = DID_ERROR << 16;
(RF_INV_E_ORDER | RF_INV_E_COUNT | } else if (pkt->entry_status & RF_BUSY) {
RF_INV_E_PARAM | RF_INV_E_TYPE)) { sp->cmd->result = DID_BUS_BUSY << 16;
sp->cmd->result = DID_ERROR << 16; } else {
} else if (pkt->entry_status & RF_BUSY) { sp->cmd->result = DID_ERROR << 16;
sp->cmd->result = DID_BUS_BUSY << 16; }
} else { qla2x00_sp_compl(ha, sp);
sp->cmd->result = DID_ERROR << 16;
} }
qla2x00_sp_compl(ha, sp);
} else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type == } else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type ==
COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7 COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7
|| pkt->entry_type == COMMAND_TYPE_6) { || pkt->entry_type == COMMAND_TYPE_6) {
......
...@@ -3690,16 +3690,6 @@ qla2x00_sp_free_dma(srb_t *sp) ...@@ -3690,16 +3690,6 @@ qla2x00_sp_free_dma(srb_t *sp)
sp->flags &= ~SRB_CRC_CTX_DMA_VALID; 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) { if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
struct ct6_dsd *ctx = sp->ctx; struct ct6_dsd *ctx = sp->ctx;
dma_pool_free(ha->fcp_cmnd_dma_pool, ctx->fcp_cmnd, 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) ...@@ -3711,6 +3701,15 @@ qla2x00_sp_final_compl(struct qla_hw_data *ha, srb_t *sp)
sp->ctx = NULL; 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); mempool_free(sp, ha->srb_mempool);
cmd->scsi_done(cmd); cmd->scsi_done(cmd);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment