#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 */
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__);
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))
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);
}
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);