mirror of https://gitee.com/openkylin/linux.git
qla2xxx: Avoid escalating the SCSI error handler if the command is not found in firmware.
If the firmware cannot find the command specified then return SUCCESS to the error handler so as not to needlessly escalate. Also cleanup the resources for the command since we cannot expect the original command to returned in interrupt context. Signed-off-by: Chad Dupuis <chad.dupuis@qlogic.com> Signed-off-by: Saurav Kashyap <saurav.kashyap@qlogic.com> Signed-off-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
f79a84bfaf
commit
f934c9d082
|
@ -1755,6 +1755,8 @@ typedef struct {
|
|||
#define CS_PORT_CONFIG_CHG 0x2A /* Port Configuration Changed */
|
||||
#define CS_PORT_BUSY 0x2B /* Port Busy */
|
||||
#define CS_COMPLETE_CHKCOND 0x30 /* Error? */
|
||||
#define CS_IOCB_ERROR 0x31 /* Generic error for IOCB request
|
||||
failure */
|
||||
#define CS_BAD_PAYLOAD 0x80 /* Driver defined */
|
||||
#define CS_UNKNOWN 0x81 /* Driver defined */
|
||||
#define CS_RETRY 0x82 /* Driver defined */
|
||||
|
|
|
@ -2644,7 +2644,10 @@ qla24xx_abort_command(srb_t *sp)
|
|||
ql_dbg(ql_dbg_mbx, vha, 0x1090,
|
||||
"Failed to complete IOCB -- completion status (%x).\n",
|
||||
le16_to_cpu(abt->nport_handle));
|
||||
rval = QLA_FUNCTION_FAILED;
|
||||
if (abt->nport_handle == CS_IOCB_ERROR)
|
||||
rval = QLA_FUNCTION_PARAMETER_ERROR;
|
||||
else
|
||||
rval = QLA_FUNCTION_FAILED;
|
||||
} else {
|
||||
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1091,
|
||||
"Done %s.\n", __func__);
|
||||
|
|
|
@ -945,7 +945,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
|
|||
int ret;
|
||||
unsigned int id, lun;
|
||||
unsigned long flags;
|
||||
int wait = 0;
|
||||
int rval, wait = 0;
|
||||
struct qla_hw_data *ha = vha->hw;
|
||||
|
||||
if (!CMD_SP(cmd))
|
||||
|
@ -974,10 +974,20 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
|
|||
sp_get(sp);
|
||||
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
if (ha->isp_ops->abort_command(sp)) {
|
||||
ret = FAILED;
|
||||
rval = ha->isp_ops->abort_command(sp);
|
||||
if (rval) {
|
||||
if (rval == QLA_FUNCTION_PARAMETER_ERROR) {
|
||||
/*
|
||||
* Decrement the ref_count since we can't find the
|
||||
* command
|
||||
*/
|
||||
atomic_dec(&sp->ref_count);
|
||||
ret = SUCCESS;
|
||||
} else
|
||||
ret = FAILED;
|
||||
|
||||
ql_dbg(ql_dbg_taskm, vha, 0x8003,
|
||||
"Abort command mbx failed cmd=%p.\n", cmd);
|
||||
"Abort command mbx failed cmd=%p, rval=%x.\n", cmd, rval);
|
||||
} else {
|
||||
ql_dbg(ql_dbg_taskm, vha, 0x8004,
|
||||
"Abort command mbx success cmd=%p.\n", cmd);
|
||||
|
@ -985,6 +995,12 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
|
|||
}
|
||||
|
||||
spin_lock_irqsave(&ha->hardware_lock, flags);
|
||||
/*
|
||||
* Clear the slot in the oustanding_cmds array if we can't find the
|
||||
* command to reclaim the resources.
|
||||
*/
|
||||
if (rval == QLA_FUNCTION_PARAMETER_ERROR)
|
||||
vha->req->outstanding_cmds[sp->handle] = NULL;
|
||||
sp->done(ha, sp, 0);
|
||||
spin_unlock_irqrestore(&ha->hardware_lock, flags);
|
||||
|
||||
|
|
Loading…
Reference in New Issue