scsi: qla2xxx: Force semaphore on flash validation failure
authorQuinn Tran <qutran@marvell.com>
Wed, 26 Feb 2020 22:40:15 +0000 (14:40 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Sat, 29 Feb 2020 01:32:34 +0000 (20:32 -0500)
For single port 28XX adapter, the second core can still run in the
background.  The flash semaphore can be held by the non-active core.
This patch tell MPI FW to check for this case and clear the semaphore
from the non-active core.

Link: https://lore.kernel.org/r/20200226224022.24518-12-hmadhani@marvell.com
Signed-off-by: Himanshu Madhani <hmadhani@marvell.com>
Signed-off-by: Quinn Tran <qutran@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/qla2xxx/qla_mbx.c

index 11a60fb..2c01deb 100644 (file)
@@ -666,10 +666,14 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
        struct qla_hw_data *ha = vha->hw;
        mbx_cmd_t mc;
        mbx_cmd_t *mcp = &mc;
+       u8 semaphore = 0;
+#define EXE_FW_FORCE_SEMAPHORE BIT_7
+       u8 retry = 3;
 
        ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1025,
            "Entered %s.\n", __func__);
 
+again:
        mcp->mb[0] = MBC_EXECUTE_FIRMWARE;
        mcp->out_mb = MBX_0;
        mcp->in_mb = MBX_0;
@@ -711,6 +715,9 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
                if (ha->flags.exchoffld_enabled)
                        mcp->mb[4] |= ENABLE_EXCHANGE_OFFLD;
 
+               if (semaphore)
+                       mcp->mb[11] |= EXE_FW_FORCE_SEMAPHORE;
+
                mcp->out_mb |= MBX_4 | MBX_3 | MBX_2 | MBX_1 | MBX_11;
                mcp->in_mb |= MBX_3 | MBX_2 | MBX_1;
        } else {
@@ -727,6 +734,15 @@ qla2x00_execute_fw(scsi_qla_host_t *vha, uint32_t risc_addr)
        rval = qla2x00_mailbox_command(vha, mcp);
 
        if (rval != QLA_SUCCESS) {
+               if (IS_QLA28XX(ha) && rval == QLA_COMMAND_ERROR &&
+                   mcp->mb[1] == 0x27 && retry) {
+                       semaphore = 1;
+                       retry--;
+                       ql_dbg(ql_dbg_async, vha, 0x1026,
+                           "Exe FW: force semaphore.\n");
+                       goto again;
+               }
+
                ql_dbg(ql_dbg_mbx, vha, 0x1026,
                    "Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
                return rval;