scsi: qla2xxx: Add support to report MPI FW state

MPI firmware state was returned as 0.  Get MPI FW state to proceed with
flash image validation.

A new sysfs node 'mpi_fw_state' is added to report MPI firmware state:

    /sys/class/scsi_host/hostXX/mpi_fw_state

Fixes: d74181ca11 ("scsi: qla2xxx: Add bsg interface to support firmware img validation")
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260305093337.2007205-1-njavali@marvell.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Nilesh Javali
2026-03-05 15:03:37 +05:30
committed by Martin K. Petersen
parent c420f7c4ac
commit 0e124af675
3 changed files with 71 additions and 2 deletions

View File

@@ -1638,7 +1638,7 @@ qla2x00_fw_state_show(struct device *dev, struct device_attribute *attr,
{
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
int rval = QLA_FUNCTION_FAILED;
uint16_t state[6];
uint16_t state[16];
uint32_t pstate;
if (IS_QLAFX00(vha->hw)) {
@@ -2402,6 +2402,63 @@ qla2x00_dport_diagnostics_show(struct device *dev,
vha->dport_data[0], vha->dport_data[1],
vha->dport_data[2], vha->dport_data[3]);
}
static ssize_t
qla2x00_mpi_fw_state_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
int rval = QLA_FUNCTION_FAILED;
u16 state[16];
u16 mpi_state;
struct qla_hw_data *ha = vha->hw;
if (!(IS_QLA27XX(ha) || IS_QLA28XX(ha)))
return scnprintf(buf, PAGE_SIZE,
"MPI state reporting is not supported for this HBA.\n");
memset(state, 0, sizeof(state));
mutex_lock(&vha->hw->optrom_mutex);
if (qla2x00_chip_is_down(vha)) {
mutex_unlock(&vha->hw->optrom_mutex);
ql_dbg(ql_dbg_user, vha, 0x70df,
"ISP reset is in progress, failing mpi_fw_state.\n");
return -EBUSY;
} else if (vha->hw->flags.eeh_busy) {
mutex_unlock(&vha->hw->optrom_mutex);
ql_dbg(ql_dbg_user, vha, 0x70ea,
"HBA in PCI error state, failing mpi_fw_state.\n");
return -EBUSY;
}
rval = qla2x00_get_firmware_state(vha, state);
mutex_unlock(&vha->hw->optrom_mutex);
if (rval != QLA_SUCCESS) {
ql_dbg(ql_dbg_user, vha, 0x70eb,
"MB Command to retrieve MPI state failed (%d), failing mpi_fw_state.\n",
rval);
return -EIO;
}
mpi_state = state[11];
if (!(mpi_state & BIT_15))
return scnprintf(buf, PAGE_SIZE,
"MPI firmware state reporting is not supported by this firmware. (0x%02x)\n",
mpi_state);
if (!(mpi_state & BIT_8))
return scnprintf(buf, PAGE_SIZE,
"MPI firmware is disabled. (0x%02x)\n",
mpi_state);
return scnprintf(buf, PAGE_SIZE,
"MPI firmware is enabled, state is %s. (0x%02x)\n",
mpi_state & BIT_9 ? "active" : "inactive",
mpi_state);
}
static DEVICE_ATTR(dport_diagnostics, 0444,
qla2x00_dport_diagnostics_show, NULL);
@@ -2469,6 +2526,8 @@ static DEVICE_ATTR(port_speed, 0644, qla2x00_port_speed_show,
qla2x00_port_speed_store);
static DEVICE_ATTR(port_no, 0444, qla2x00_port_no_show, NULL);
static DEVICE_ATTR(fw_attr, 0444, qla2x00_fw_attr_show, NULL);
static DEVICE_ATTR(mpi_fw_state, 0444, qla2x00_mpi_fw_state_show, NULL);
static struct attribute *qla2x00_host_attrs[] = {
&dev_attr_driver_version.attr.attr,
@@ -2517,6 +2576,7 @@ static struct attribute *qla2x00_host_attrs[] = {
&dev_attr_qlini_mode.attr,
&dev_attr_ql2xiniexchg.attr,
&dev_attr_ql2xexchoffld.attr,
&dev_attr_mpi_fw_state.attr,
NULL,
};

View File

@@ -4914,7 +4914,7 @@ qla2x00_fw_ready(scsi_qla_host_t *vha)
unsigned long wtime, mtime, cs84xx_time;
uint16_t min_wait; /* Minimum wait time if loop is down */
uint16_t wait_time; /* Wait time if loop is coming ready */
uint16_t state[6];
uint16_t state[16];
struct qla_hw_data *ha = vha->hw;
if (IS_QLAFX00(vha->hw))

View File

@@ -2268,6 +2268,13 @@ qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
else
mcp->in_mb = MBX_1|MBX_0;
if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
mcp->mb[12] = 0;
mcp->out_mb |= MBX_12;
mcp->in_mb |= MBX_12;
}
mcp->tov = MBX_TOV_SECONDS;
mcp->flags = 0;
rval = qla2x00_mailbox_command(vha, mcp);
@@ -2280,6 +2287,8 @@ qla2x00_get_firmware_state(scsi_qla_host_t *vha, uint16_t *states)
states[3] = mcp->mb[4];
states[4] = mcp->mb[5];
states[5] = mcp->mb[6]; /* DPORT status */
if (IS_QLA27XX(ha) || IS_QLA28XX(ha))
states[11] = mcp->mb[12]; /* MPI state. */
}
if (rval != QLA_SUCCESS) {