aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla2xxx/qla_isr.c
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/qla2xxx/qla_isr.c
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/qla2xxx/qla_isr.c')
-rw-r--r--drivers/scsi/qla2xxx/qla_isr.c73
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
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) {