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/qla2xxx/qla_isr.c | |
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/qla2xxx/qla_isr.c')
-rw-r--r-- | drivers/scsi/qla2xxx/qla_isr.c | 73 |
1 files changed, 52 insertions, 21 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) { |