aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorGiridhar Malavali <giridhar.malavali@qlogic.com>2011-11-18 12:03:08 -0500
committerJames Bottomley <JBottomley@Parallels.com>2011-12-15 01:55:02 -0500
commitc4631191c44de9567ac5376e6a7f4a244c2283bc (patch)
treea3e12ef92fb4d2f0177158b71d47f88d85dbfea1 /drivers/scsi
parentcfb0919c12a33132f75fb91971bbd8bdd44ebb90 (diff)
[SCSI] qla2xxx: Proper cleanup of pass through commands when firmware returns error.
[jejb: fixed up checkpatch and casting errors] Signed-off-by: Giridhar Malavali <giridhar.malavali@qlogic.com> Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c73
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c19
2 files changed, 61 insertions, 31 deletions
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
index b6023e9636ea..6426c7ed9ccc 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)
1895 } 1895 }
1896} 1896}
1897 1897
1898static int
1899qla2x00_free_sp_ctx(scsi_qla_host_t *vha, srb_t *sp)
1900{
1901 struct qla_hw_data *ha = vha->hw;
1902 struct srb_ctx *ctx;
1903
1904 if (!sp->ctx)
1905 return 1;
1906
1907 ctx = sp->ctx;
1908
1909 if (ctx->type == SRB_LOGIN_CMD ||
1910 ctx->type == SRB_LOGOUT_CMD ||
1911 ctx->type == SRB_TM_CMD) {
1912 ctx->u.iocb_cmd->done(sp);
1913 return 0;
1914 } else if (ctx->type == SRB_ADISC_CMD) {
1915 ctx->u.iocb_cmd->free(sp);
1916 return 0;
1917 } else {
1918 struct fc_bsg_job *bsg_job;
1919
1920 bsg_job = ctx->u.bsg_job;
1921 if (ctx->type == SRB_ELS_CMD_HST ||
1922 ctx->type == SRB_CT_CMD)
1923 kfree(sp->fcport);
1924
1925 bsg_job->reply->reply_data.ctels_reply.status =
1926 FC_CTELS_STATUS_OK;
1927 bsg_job->reply->result = DID_ERROR << 16;
1928 bsg_job->reply->reply_payload_rcv_len = 0;
1929 kfree(sp->ctx);
1930 mempool_free(sp, ha->srb_mempool);
1931 bsg_job->job_done(bsg_job);
1932 return 0;
1933 }
1934 return 1;
1935}
1936
1898/** 1937/**
1899 * qla2x00_error_entry() - Process an error entry. 1938 * qla2x00_error_entry() - Process an error entry.
1900 * @ha: SCSI driver HA context 1939 * @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{ 1944{
1906 srb_t *sp; 1945 srb_t *sp;
1907 struct qla_hw_data *ha = vha->hw; 1946 struct qla_hw_data *ha = vha->hw;
1908 uint32_t handle = LSW(pkt->handle); 1947 const char func[] = "ERROR-IOCB";
1909 uint16_t que = MSW(pkt->handle); 1948 uint16_t que = MSW(pkt->handle);
1910 struct req_que *req = ha->req_q_map[que]; 1949 struct req_que *req = ha->req_q_map[que];
1911 1950
@@ -1928,28 +1967,20 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt)
1928 ql_dbg(ql_dbg_async, vha, 0x502f, 1967 ql_dbg(ql_dbg_async, vha, 0x502f,
1929 "UNKNOWN flag error.\n"); 1968 "UNKNOWN flag error.\n");
1930 1969
1931 /* Validate handle. */ 1970 sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
1932 if (handle < MAX_OUTSTANDING_COMMANDS)
1933 sp = req->outstanding_cmds[handle];
1934 else
1935 sp = NULL;
1936
1937 if (sp) { 1971 if (sp) {
1938 /* Free outstanding command slot. */ 1972 if (qla2x00_free_sp_ctx(vha, sp)) {
1939 req->outstanding_cmds[handle] = NULL; 1973 if (pkt->entry_status &
1940 1974 (RF_INV_E_ORDER | RF_INV_E_COUNT |
1941 /* Bad payload or header */ 1975 RF_INV_E_PARAM | RF_INV_E_TYPE)) {
1942 if (pkt->entry_status & 1976 sp->cmd->result = DID_ERROR << 16;
1943 (RF_INV_E_ORDER | RF_INV_E_COUNT | 1977 } else if (pkt->entry_status & RF_BUSY) {
1944 RF_INV_E_PARAM | RF_INV_E_TYPE)) { 1978 sp->cmd->result = DID_BUS_BUSY << 16;
1945 sp->cmd->result = DID_ERROR << 16; 1979 } else {
1946 } else if (pkt->entry_status & RF_BUSY) { 1980 sp->cmd->result = DID_ERROR << 16;
1947 sp->cmd->result = DID_BUS_BUSY << 16; 1981 }
1948 } else { 1982 qla2x00_sp_compl(ha, sp);
1949 sp->cmd->result = DID_ERROR << 16;
1950 } 1983 }
1951 qla2x00_sp_compl(ha, sp);
1952
1953 } else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type == 1984 } else if (pkt->entry_type == COMMAND_A64_TYPE || pkt->entry_type ==
1954 COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7 1985 COMMAND_TYPE || pkt->entry_type == COMMAND_TYPE_7
1955 || pkt->entry_type == COMMAND_TYPE_6) { 1986 || pkt->entry_type == COMMAND_TYPE_6) {
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index ae1699f6854d..c9a74521b402 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)
3690 sp->flags &= ~SRB_CRC_CTX_DMA_VALID; 3690 sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
3691 } 3691 }
3692 3692
3693 CMD_SP(cmd) = NULL;
3694}
3695
3696static void
3697qla2x00_sp_final_compl(struct qla_hw_data *ha, srb_t *sp)
3698{
3699 struct scsi_cmnd *cmd = sp->cmd;
3700
3701 qla2x00_sp_free_dma(sp);
3702
3703 if (sp->flags & SRB_FCP_CMND_DMA_VALID) { 3693 if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
3704 struct ct6_dsd *ctx = sp->ctx; 3694 struct ct6_dsd *ctx = sp->ctx;
3705 dma_pool_free(ha->fcp_cmnd_dma_pool, ctx->fcp_cmnd, 3695 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 sp->ctx = NULL; 3701 sp->ctx = NULL;
3712 } 3702 }
3713 3703
3704 CMD_SP(cmd) = NULL;
3705}
3706
3707static void
3708qla2x00_sp_final_compl(struct qla_hw_data *ha, srb_t *sp)
3709{
3710 struct scsi_cmnd *cmd = sp->cmd;
3711
3712 qla2x00_sp_free_dma(sp);
3714 mempool_free(sp, ha->srb_mempool); 3713 mempool_free(sp, ha->srb_mempool);
3715 cmd->scsi_done(cmd); 3714 cmd->scsi_done(cmd);
3716} 3715}