diff options
author | Giridhar Malavali <giridhar.malavali@qlogic.com> | 2011-11-18 12:03:08 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-12-15 01:55:02 -0500 |
commit | c4631191c44de9567ac5376e6a7f4a244c2283bc (patch) | |
tree | a3e12ef92fb4d2f0177158b71d47f88d85dbfea1 /drivers/scsi | |
parent | cfb0919c12a33132f75fb91971bbd8bdd44ebb90 (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.c | 73 | ||||
-rw-r--r-- | 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 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 | ||
1898 | static int | ||
1899 | qla2x00_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 | |||
3696 | static void | ||
3697 | qla2x00_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 | |||
3707 | static void | ||
3708 | qla2x00_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 | } |