qla2xxx: Avoid escalating the SCSI error handler if the command is not found in firmware.
authorChad Dupuis <chad.dupuis@qlogic.com>
Fri, 11 Apr 2014 20:54:31 +0000 (16:54 -0400)
committerChristoph Hellwig <hch@lst.de>
Mon, 19 May 2014 11:31:03 +0000 (13:31 +0200)
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>
drivers/scsi/qla2xxx/qla_def.h
drivers/scsi/qla2xxx/qla_mbx.c
drivers/scsi/qla2xxx/qla_os.c

index a81e8bab6f038a6d5e0afc18fe2e36a93050128f..6c9724c1c5a45d422cdeb8129efc7d2ded3ee5da 100644 (file)
@@ -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 */
index a2e3787e4112243da713608f94083e71f7b1db39..01d9f54a32229124806cface0e673defb6b2000e 100644 (file)
@@ -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__);
index b182d27695cf4e4efc89e05d68e12ec734181217..8f1a098d270e35862825e21de3ec8d1048041acf 100644 (file)
@@ -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);