Skip to content

Commit f4f250c

Browse files
Arun Easigregkh
authored andcommitted
scsi: qla2xxx: Fix reset of MPI firmware
commit 3e6efab upstream. Normally, the MPI firmware is reset when an MPI dump is collected. If an unsaved MPI dump exists in the driver, though, an alternate mechanism is used. This mechanism, which was not fully correct, is not recommended and instead an MPI dump template walk is suggested to perform the MPI reset. To allow for the MPI dump template walk, extra space is reserved in the MPI dump buffer which gets used only when there is already an MPI dump in place. Link: https://lore.kernel.org/r/20200929102152.32278-5-njavali@marvell.com Fixes: cbb01c2 ("scsi: qla2xxx: Fix MPI failure AEN (8200) handling") Cc: stable@vger.kernel.org Reviewed-by: Himanshu Madhani <himanshu.madhani@oracle.com> Signed-off-by: Arun Easi <aeasi@marvell.com> Signed-off-by: Nilesh Javali <njavali@marvell.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 26474cd commit f4f250c

4 files changed

Lines changed: 23 additions & 39 deletions

File tree

drivers/scsi/qla2xxx/qla_attr.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,14 @@ qla2x00_sysfs_write_fw_dump(struct file *filp, struct kobject *kobj,
157157
vha->host_no);
158158
}
159159
break;
160+
case 10:
161+
if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
162+
ql_log(ql_log_info, vha, 0x70e9,
163+
"Issuing MPI firmware dump on host#%ld.\n",
164+
vha->host_no);
165+
ha->isp_ops->mpi_fw_dump(vha, 0);
166+
}
167+
break;
160168
}
161169
return count;
162170
}
@@ -744,8 +752,6 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
744752
qla83xx_idc_audit(vha, IDC_AUDIT_TIMESTAMP);
745753
qla83xx_idc_unlock(vha, 0);
746754
break;
747-
} else if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
748-
qla27xx_reset_mpi(vha);
749755
} else {
750756
/* Make sure FC side is not in reset */
751757
WARN_ON_ONCE(qla2x00_wait_for_hba_online(vha) !=

drivers/scsi/qla2xxx/qla_gbl.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -938,6 +938,5 @@ extern void qla24xx_process_purex_list(struct purex_list *);
938938

939939
/* nvme.c */
940940
void qla_nvme_unregister_remote_port(struct fc_port *fcport);
941-
void qla27xx_reset_mpi(scsi_qla_host_t *vha);
942941
void qla_handle_els_plogi_done(scsi_qla_host_t *vha, struct event_arg *ea);
943942
#endif /* _QLA_GBL_H */

drivers/scsi/qla2xxx/qla_init.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3298,6 +3298,8 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
32983298
j, fwdt->dump_size);
32993299
dump_size += fwdt->dump_size;
33003300
}
3301+
/* Add space for spare MPI fw dump. */
3302+
dump_size += ha->fwdt[1].dump_size;
33013303
} else {
33023304
req_q_size = req->length * sizeof(request_t);
33033305
rsp_q_size = rsp->length * sizeof(response_t);

drivers/scsi/qla2xxx/qla_tmpl.c

Lines changed: 13 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -12,33 +12,6 @@
1212
#define IOBASE(vha) IOBAR(ISPREG(vha))
1313
#define INVALID_ENTRY ((struct qla27xx_fwdt_entry *)0xffffffffffffffffUL)
1414

15-
/* hardware_lock assumed held. */
16-
static void
17-
qla27xx_write_remote_reg(struct scsi_qla_host *vha,
18-
u32 addr, u32 data)
19-
{
20-
struct device_reg_24xx __iomem *reg = &vha->hw->iobase->isp24;
21-
22-
ql_dbg(ql_dbg_misc, vha, 0xd300,
23-
"%s: addr/data = %xh/%xh\n", __func__, addr, data);
24-
25-
wrt_reg_dword(&reg->iobase_addr, 0x40);
26-
wrt_reg_dword(&reg->iobase_c4, data);
27-
wrt_reg_dword(&reg->iobase_window, addr);
28-
}
29-
30-
void
31-
qla27xx_reset_mpi(scsi_qla_host_t *vha)
32-
{
33-
ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd301,
34-
"Entered %s.\n", __func__);
35-
36-
qla27xx_write_remote_reg(vha, 0x104050, 0x40004);
37-
qla27xx_write_remote_reg(vha, 0x10405c, 0x4);
38-
39-
vha->hw->stat.num_mpi_reset++;
40-
}
41-
4215
static inline void
4316
qla27xx_insert16(uint16_t value, void *buf, ulong *len)
4417
{
@@ -1028,22 +1001,27 @@ void
10281001
qla27xx_mpi_fwdump(scsi_qla_host_t *vha, int hardware_locked)
10291002
{
10301003
ulong flags = 0;
1031-
bool need_mpi_reset = true;
10321004

10331005
#ifndef __CHECKER__
10341006
if (!hardware_locked)
10351007
spin_lock_irqsave(&vha->hw->hardware_lock, flags);
10361008
#endif
10371009
if (!vha->hw->mpi_fw_dump) {
10381010
ql_log(ql_log_warn, vha, 0x02f3, "-> mpi_fwdump no buffer\n");
1039-
} else if (vha->hw->mpi_fw_dumped) {
1040-
ql_log(ql_log_warn, vha, 0x02f4,
1041-
"-> MPI firmware already dumped (%p) -- ignoring request\n",
1042-
vha->hw->mpi_fw_dump);
10431011
} else {
10441012
struct fwdt *fwdt = &vha->hw->fwdt[1];
10451013
ulong len;
10461014
void *buf = vha->hw->mpi_fw_dump;
1015+
bool walk_template_only = false;
1016+
1017+
if (vha->hw->mpi_fw_dumped) {
1018+
/* Use the spare area for any further dumps. */
1019+
buf += fwdt->dump_size;
1020+
walk_template_only = true;
1021+
ql_log(ql_log_warn, vha, 0x02f4,
1022+
"-> MPI firmware already dumped -- dump saving to temporary buffer %p.\n",
1023+
buf);
1024+
}
10471025

10481026
ql_log(ql_log_warn, vha, 0x02f5, "-> fwdt1 running...\n");
10491027
if (!fwdt->template) {
@@ -1058,9 +1036,10 @@ qla27xx_mpi_fwdump(scsi_qla_host_t *vha, int hardware_locked)
10581036
ql_log(ql_log_warn, vha, 0x02f7,
10591037
"-> fwdt1 fwdump residual=%+ld\n",
10601038
fwdt->dump_size - len);
1061-
} else {
1062-
need_mpi_reset = false;
10631039
}
1040+
vha->hw->stat.num_mpi_reset++;
1041+
if (walk_template_only)
1042+
goto bailout;
10641043

10651044
vha->hw->mpi_fw_dump_len = len;
10661045
vha->hw->mpi_fw_dumped = 1;
@@ -1072,8 +1051,6 @@ qla27xx_mpi_fwdump(scsi_qla_host_t *vha, int hardware_locked)
10721051
}
10731052

10741053
bailout:
1075-
if (need_mpi_reset)
1076-
qla27xx_reset_mpi(vha);
10771054
#ifndef __CHECKER__
10781055
if (!hardware_locked)
10791056
spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);

0 commit comments

Comments
 (0)