Merge branch 'svn-trunk'

This commit is contained in:
Bart Van Assche
2020-05-06 09:07:43 -07:00
11 changed files with 322 additions and 132 deletions
+1 -1
View File
@@ -46,7 +46,7 @@ INSTALL_DIR := $(INSTALL_MOD_PATH)/lib/modules/$(KVER)/extra
ifneq ($(PATCHLEVEL),)
ccflags-y += $(call cc-option,-Wextra) -Wno-unused-parameter \
-Wno-missing-field-initializers -I$(src)/../scst/include\
-Wno-missing-field-initializers -I$(src)/../scst/include -I$(src)\
-DDEFAULT_SYMBOL_NAMESPACE=QLA32GB
ifneq ($(CONFIG_SCSI_QLA2XXX_TARGET),)
+27 -3
View File
@@ -26,7 +26,8 @@ qla2x00_sysfs_read_fw_dump(struct file *filp, struct kobject *kobj,
struct qla_hw_data *ha = vha->hw;
int rval = 0;
if (!(ha->fw_dump_reading || ha->mctp_dump_reading))
if (!(ha->fw_dump_reading || ha->mctp_dump_reading ||
ha->mpi_fw_dump_reading))
return 0;
mutex_lock(&ha->optrom_mutex);
@@ -42,6 +43,10 @@ qla2x00_sysfs_read_fw_dump(struct file *filp, struct kobject *kobj,
} else if (ha->mctp_dumped && ha->mctp_dump_reading) {
rval = memory_read_from_buffer(buf, count, &off, ha->mctp_dump,
MCTP_DUMP_SIZE);
} else if (ha->mpi_fw_dumped && ha->mpi_fw_dump_reading) {
rval = memory_read_from_buffer(buf, count, &off,
ha->mpi_fw_dump,
ha->mpi_fw_dump_len);
} else if (ha->fw_dump_reading) {
rval = memory_read_from_buffer(buf, count, &off, ha->fw_dump,
ha->fw_dump_len);
@@ -103,7 +108,6 @@ qla2x00_sysfs_write_fw_dump(struct file *filp, struct kobject *kobj,
qla82xx_set_reset_owner(vha);
qla8044_idc_unlock(ha);
} else {
ha->fw_dump_mpi = 1;
qla2x00_system_error(vha);
}
break;
@@ -137,6 +141,22 @@ qla2x00_sysfs_write_fw_dump(struct file *filp, struct kobject *kobj,
vha->host_no);
}
break;
case 8:
if (!ha->mpi_fw_dump_reading)
break;
ql_log(ql_log_info, vha, 0x70e7,
"MPI firmware dump cleared on (%ld).\n", vha->host_no);
ha->mpi_fw_dump_reading = 0;
ha->mpi_fw_dumped = 0;
break;
case 9:
if (ha->mpi_fw_dumped && !ha->mpi_fw_dump_reading) {
ha->mpi_fw_dump_reading = 1;
ql_log(ql_log_info, vha, 0x70e8,
"Raw MPI firmware dump ready for read on (%ld).\n",
vha->host_no);
}
break;
}
return count;
}
@@ -706,7 +726,8 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
scsi_unblock_requests(vha->host);
break;
case 0x2025d:
if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha))
if (!IS_QLA81XX(ha) && !IS_QLA83XX(ha) &&
!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
return -EPERM;
ql_log(ql_log_info, vha, 0x706f,
@@ -724,6 +745,8 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
qla83xx_idc_audit(vha, IDC_AUDIT_TIMESTAMP);
qla83xx_idc_unlock(vha, 0);
break;
} else if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
qla27xx_reset_mpi(vha);
} else {
/* Make sure FC side is not in reset */
WARN_ON_ONCE(qla2x00_wait_for_hba_online(vha) !=
@@ -737,6 +760,7 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj,
scsi_unblock_requests(vha->host);
break;
}
break;
case 0x2025e:
if (!IS_P3P_TYPE(ha) || vha != base_vha) {
ql_log(ql_log_info, vha, 0x7071,
+38 -21
View File
@@ -73,6 +73,8 @@
#include "qla_def.h"
#include <linux/delay.h>
#define CREATE_TRACE_POINTS
#include <trace/events/qla.h>
static uint32_t ql_dbg_offset = 0x800;
@@ -776,16 +778,16 @@ qla2300_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
if (rval == QLA_SUCCESS) {
dmp_reg = &reg->flash_address;
for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++, dmp_reg++)
for (cnt = 0; cnt < ARRAY_SIZE(fw->pbiu_reg); cnt++, dmp_reg++)
fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg));
dmp_reg = &reg->u.isp2300.req_q_in;
for (cnt = 0; cnt < sizeof(fw->risc_host_reg) / 2;
for (cnt = 0; cnt < ARRAY_SIZE(fw->risc_host_reg);
cnt++, dmp_reg++)
fw->risc_host_reg[cnt] = htons(RD_REG_WORD(dmp_reg));
dmp_reg = &reg->u.isp2300.mailbox0;
for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2;
for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg);
cnt++, dmp_reg++)
fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg));
@@ -797,7 +799,7 @@ qla2300_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
WRT_REG_WORD(&reg->ctrl_status, 0x00);
dmp_reg = &reg->risc_hw;
for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2;
for (cnt = 0; cnt < ARRAY_SIZE(fw->risc_hdw_reg);
cnt++, dmp_reg++)
fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg));
@@ -858,12 +860,12 @@ qla2300_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
/* Get RISC SRAM. */
if (rval == QLA_SUCCESS)
rval = qla2xxx_dump_ram(ha, 0x800, fw->risc_ram,
sizeof(fw->risc_ram) / 2, &nxt);
ARRAY_SIZE(fw->risc_ram), &nxt);
/* Get stack SRAM. */
if (rval == QLA_SUCCESS)
rval = qla2xxx_dump_ram(ha, 0x10000, fw->stack_ram,
sizeof(fw->stack_ram) / 2, &nxt);
ARRAY_SIZE(fw->stack_ram), &nxt);
/* Get data SRAM. */
if (rval == QLA_SUCCESS)
@@ -942,7 +944,7 @@ qla2100_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
}
if (rval == QLA_SUCCESS) {
dmp_reg = &reg->flash_address;
for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++, dmp_reg++)
for (cnt = 0; cnt < ARRAY_SIZE(fw->pbiu_reg); cnt++, dmp_reg++)
fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg));
dmp_reg = &reg->u.isp2100.mailbox0;
@@ -954,12 +956,12 @@ qla2100_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
}
dmp_reg = &reg->u.isp2100.unused_2[0];
for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++, dmp_reg++)
for (cnt = 0; cnt < ARRAY_SIZE(fw->dma_reg); cnt++, dmp_reg++)
fw->dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg));
WRT_REG_WORD(&reg->ctrl_status, 0x00);
dmp_reg = &reg->risc_hw;
for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++, dmp_reg++)
for (cnt = 0; cnt < ARRAY_SIZE(fw->risc_hdw_reg); cnt++, dmp_reg++)
fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg));
WRT_REG_WORD(&reg->pcr, 0x2000);
@@ -1039,7 +1041,7 @@ qla2100_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
WRT_MAILBOX_REG(ha, reg, 0, MBC_READ_RAM_WORD);
clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags);
}
for (cnt = 0; cnt < sizeof(fw->risc_ram) / 2 && rval == QLA_SUCCESS;
for (cnt = 0; cnt < ARRAY_SIZE(fw->risc_ram) && rval == QLA_SUCCESS;
cnt++, risc_address++) {
WRT_MAILBOX_REG(ha, reg, 1, risc_address);
WRT_REG_WORD(&reg->hccr, HCCR_SET_HOST_INT);
@@ -1143,7 +1145,7 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
/* Host interface registers. */
dmp_reg = &reg->flash_addr;
for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++, dmp_reg++)
for (cnt = 0; cnt < ARRAY_SIZE(fw->host_reg); cnt++, dmp_reg++)
fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg));
/* Disable interrupts. */
@@ -1176,7 +1178,7 @@ qla24xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
/* Mailbox registers. */
mbx_reg = &reg->mailbox0;
for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++, mbx_reg++)
for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg); cnt++, mbx_reg++)
fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg));
/* Transfer sequence registers. */
@@ -1419,7 +1421,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
/* Host interface registers. */
dmp_reg = &reg->flash_addr;
for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++, dmp_reg++)
for (cnt = 0; cnt < ARRAY_SIZE(fw->host_reg); cnt++, dmp_reg++)
fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg));
/* Disable interrupts. */
@@ -1468,7 +1470,7 @@ qla25xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
/* Mailbox registers. */
mbx_reg = &reg->mailbox0;
for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++, mbx_reg++)
for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg); cnt++, mbx_reg++)
fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg));
/* Transfer sequence registers. */
@@ -1743,7 +1745,7 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
/* Host interface registers. */
dmp_reg = &reg->flash_addr;
for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++, dmp_reg++)
for (cnt = 0; cnt < ARRAY_SIZE(fw->host_reg); cnt++, dmp_reg++)
fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg));
/* Disable interrupts. */
@@ -1792,7 +1794,7 @@ qla81xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
/* Mailbox registers. */
mbx_reg = &reg->mailbox0;
for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++, mbx_reg++)
for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg); cnt++, mbx_reg++)
fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg));
/* Transfer sequence registers. */
@@ -2091,7 +2093,7 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
/* Host interface registers. */
dmp_reg = &reg->flash_addr;
for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++, dmp_reg++)
for (cnt = 0; cnt < ARRAY_SIZE(fw->host_reg); cnt++, dmp_reg++)
fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg));
/* Disable interrupts. */
@@ -2140,7 +2142,7 @@ qla83xx_fw_dump(scsi_qla_host_t *vha, int hardware_locked)
/* Mailbox registers. */
mbx_reg = &reg->mailbox0;
for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++, mbx_reg++)
for (cnt = 0; cnt < ARRAY_SIZE(fw->mailbox_reg); cnt++, mbx_reg++)
fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg));
/* Transfer sequence registers. */
@@ -2537,15 +2539,30 @@ ql_dbg(uint level, scsi_qla_host_t *vha, uint id, const char *fmt, ...)
{
va_list va;
struct va_format vaf;
if (!ql_mask_match(level))
return;
char pbuf[64];
va_start(va, fmt);
vaf.fmt = fmt;
vaf.va = &va;
if (!ql_mask_match(level)) {
if (vha != NULL) {
const struct pci_dev *pdev = vha->hw->pdev;
/* <module-name> <msg-id>:<host> Message */
snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x:%ld: ",
QL_MSGHDR, dev_name(&(pdev->dev)), id,
vha->host_no);
} else {
snprintf(pbuf, sizeof(pbuf), "%s [%s]-%04x: : ",
QL_MSGHDR, "0000:00:00.0", id);
}
pbuf[sizeof(pbuf) - 1] = 0;
trace_ql_dbg_log(pbuf, &vaf);
va_end(va);
return;
}
if (vha != NULL) {
const struct pci_dev *pdev = vha->hw->pdev;
/* <module-name> <pci-name> <msg-id>:<host> Message */
+12 -1
View File
@@ -3250,6 +3250,7 @@ struct isp_operations {
uint32_t);
void (*fw_dump) (struct scsi_qla_host *, int);
void (*mpi_fw_dump)(struct scsi_qla_host *, int);
int (*beacon_on) (struct scsi_qla_host *);
int (*beacon_off) (struct scsi_qla_host *);
@@ -3775,6 +3776,11 @@ struct qlt_hw_data {
#define LEAK_EXCHG_THRESH_HOLD_PERCENT 75 /* 75 percent */
struct qla_hw_data_stat {
u32 num_fw_dump;
u32 num_mpi_reset;
};
/*
* Qlogic host adapter specific data structure.
*/
@@ -4257,7 +4263,6 @@ struct qla_hw_data {
uint32_t fw_dump_len;
u32 fw_dump_alloc_len;
bool fw_dumped;
bool fw_dump_mpi;
unsigned long fw_dump_cap_flags;
#define RISC_PAUSE_CMPL 0
#define DMA_SHUTDOWN_CMPL 1
@@ -4268,6 +4273,10 @@ struct qla_hw_data {
#define ISP_MBX_RDY 6
#define ISP_SOFT_RESET_CMPL 7
int fw_dump_reading;
void *mpi_fw_dump;
u32 mpi_fw_dump_len;
unsigned int mpi_fw_dump_reading:1;
unsigned int mpi_fw_dumped:1;
int prev_minidump_failed;
dma_addr_t eft_dma;
void *eft;
@@ -4481,6 +4490,8 @@ struct qla_hw_data {
uint16_t last_zio_threshold;
#define DEFAULT_ZIO_THRESHOLD 5
struct qla_hw_data_stat stat;
};
struct active_regions {
+3
View File
@@ -177,6 +177,7 @@ extern int ql2xenablemsix;
extern int qla2xuseresexchforels;
extern int ql2xexlogins;
extern int ql2xdifbundlinginternalbuffers;
extern int ql2xfulldump_on_mpifail;
extern int qla2x00_loop_reset(scsi_qla_host_t *);
extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
@@ -649,6 +650,7 @@ extern void qla82xx_fw_dump(scsi_qla_host_t *, int);
extern void qla8044_fw_dump(scsi_qla_host_t *, int);
extern void qla27xx_fwdump(scsi_qla_host_t *, int);
extern void qla27xx_mpi_fwdump(scsi_qla_host_t *, int);
extern ulong qla27xx_fwdt_calculate_dump_size(struct scsi_qla_host *, void *);
extern int qla27xx_fwdt_template_valid(void *);
extern ulong qla27xx_fwdt_template_size(void *);
@@ -942,5 +944,6 @@ extern void qla24xx_process_purex_list(struct purex_list *);
/* nvme.c */
void qla_nvme_unregister_remote_port(struct fc_port *fcport);
void qla27xx_reset_mpi(scsi_qla_host_t *vha);
void qla_handle_els_plogi_done(scsi_qla_host_t *vha, struct event_arg *ea);
#endif /* _QLA_GBL_H */
+52 -42
View File
@@ -3339,6 +3339,8 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
dump_size / 1024);
if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
ha->mpi_fw_dump = (char *)fw_dump +
ha->fwdt[1].dump_size;
mutex_unlock(&ha->optrom_mutex);
return;
}
@@ -5081,6 +5083,54 @@ qla2x00_configure_loop(scsi_qla_host_t *vha)
return (rval);
}
static int qla2x00_configure_n2n_loop(scsi_qla_host_t *vha)
{
struct qla_hw_data *ha = vha->hw;
unsigned long flags;
fc_port_t *fcport;
int rval;
if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags)) {
/* borrowing */
u32 *bp, sz;
memset(ha->init_cb, 0, ha->init_cb_size);
sz = min_t(int, sizeof(struct els_plogi_payload),
ha->init_cb_size);
rval = qla24xx_get_port_login_templ(vha, ha->init_cb_dma,
ha->init_cb, sz);
if (rval == QLA_SUCCESS) {
__be32 *q = &ha->plogi_els_payld.data[0];
bp = (uint32_t *)ha->init_cb;
cpu_to_be32_array(q, bp, sz / 4);
memcpy(bp, q, sizeof(ha->plogi_els_payld.data));
} else {
ql_dbg(ql_dbg_init, vha, 0x00d1,
"PLOGI ELS param read fail.\n");
goto skip_login;
}
}
list_for_each_entry(fcport, &vha->vp_fcports, list) {
if (fcport->n2n_flag) {
qla24xx_fcport_handle_login(vha, fcport);
return QLA_SUCCESS;
}
}
skip_login:
spin_lock_irqsave(&vha->work_lock, flags);
vha->scan.scan_retry++;
spin_unlock_irqrestore(&vha->work_lock, flags);
if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
}
return QLA_FUNCTION_FAILED;
}
/*
* qla2x00_configure_local_loop
* Updates Fibre Channel Device Database with local loop devices.
@@ -5098,7 +5148,6 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
int found_devs;
int found;
fc_port_t *fcport, *new_fcport;
uint16_t index;
uint16_t entries;
struct gid_list_info *gid;
@@ -5108,47 +5157,8 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha)
unsigned long flags;
/* Inititae N2N login. */
if (N2N_TOPO(ha)) {
if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags)) {
/* borrowing */
u32 *bp, sz;
memset(ha->init_cb, 0, ha->init_cb_size);
sz = min_t(int, sizeof(struct els_plogi_payload),
ha->init_cb_size);
rval = qla24xx_get_port_login_templ(vha,
ha->init_cb_dma, (void *)ha->init_cb, sz);
if (rval == QLA_SUCCESS) {
__be32 *q = &ha->plogi_els_payld.data[0];
bp = (uint32_t *)ha->init_cb;
cpu_to_be32_array(q, bp, sz / 4);
memcpy(bp, q, sizeof(ha->plogi_els_payld.data));
} else {
ql_dbg(ql_dbg_init, vha, 0x00d1,
"PLOGI ELS param read fail.\n");
goto skip_login;
}
}
list_for_each_entry(fcport, &vha->vp_fcports, list) {
if (fcport->n2n_flag) {
qla24xx_fcport_handle_login(vha, fcport);
return QLA_SUCCESS;
}
}
skip_login:
spin_lock_irqsave(&vha->work_lock, flags);
vha->scan.scan_retry++;
spin_unlock_irqrestore(&vha->work_lock, flags);
if (vha->scan.scan_retry < MAX_SCAN_RETRIES) {
set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
}
return QLA_FUNCTION_FAILED;
}
if (N2N_TOPO(ha))
return qla2x00_configure_n2n_loop(vha);
found_devs = 0;
new_fcport = NULL;
+37 -17
View File
@@ -769,6 +769,39 @@ qla2x00_find_fcport_by_nportid(scsi_qla_host_t *vha, port_id_t *id,
return NULL;
}
/* Shall be called only on supported adapters. */
static void
qla27xx_handle_8200_aen(scsi_qla_host_t *vha, uint16_t *mb)
{
struct qla_hw_data *ha = vha->hw;
bool reset_isp_needed = 0;
ql_log(ql_log_warn, vha, 0x02f0,
"MPI Heartbeat stop. MPI reset is%s needed. "
"MB0[%xh] MB1[%xh] MB2[%xh] MB3[%xh]\n",
mb[0] & BIT_8 ? "" : " not",
mb[0], mb[1], mb[2], mb[3]);
if ((mb[1] & BIT_8) == 0)
return;
ql_log(ql_log_warn, vha, 0x02f1,
"MPI Heartbeat stop. FW dump needed\n");
if (ql2xfulldump_on_mpifail) {
ha->isp_ops->fw_dump(vha, 1);
reset_isp_needed = 1;
}
ha->isp_ops->mpi_fw_dump(vha, 1);
if (reset_isp_needed) {
vha->hw->flags.fw_init_done = 0;
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
qla2xxx_wake_dpc(vha);
}
}
/**
* qla2x00_async_event() - Process aynchronous events.
* @vha: SCSI driver HA context
@@ -884,9 +917,9 @@ skip_rio:
"ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n ",
mb[1], mb[2], mb[3]);
ha->fw_dump_mpi =
(IS_QLA27XX(ha) || IS_QLA28XX(ha)) &&
RD_REG_WORD(&reg24->mailbox7) & BIT_8;
if ((IS_QLA27XX(ha) || IS_QLA28XX(ha)) &&
RD_REG_WORD(&reg24->mailbox7) & BIT_8)
ha->isp_ops->mpi_fw_dump(vha, 1);
ha->isp_ops->fw_dump(vha, 1);
ha->flags.fw_init_done = 0;
QLA_FW_STOPPED(ha);
@@ -1387,20 +1420,7 @@ global_port_update:
case MBA_IDC_AEN:
if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
ha->flags.fw_init_done = 0;
ql_log(ql_log_warn, vha, 0xffff,
"MPI Heartbeat stop. Chip reset needed. MB0[%xh] MB1[%xh] MB2[%xh] MB3[%xh]\n",
mb[0], mb[1], mb[2], mb[3]);
if ((mb[1] & BIT_8) ||
(mb[2] & BIT_8)) {
ql_log(ql_log_warn, vha, 0xd013,
"MPI Heartbeat stop. FW dump needed\n");
ha->fw_dump_mpi = 1;
ha->isp_ops->fw_dump(vha, 1);
}
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
qla2xxx_wake_dpc(vha);
qla27xx_handle_8200_aen(vha, mb);
} else if (IS_QLA83XX(ha)) {
mb[4] = RD_REG_WORD(&reg24->mailbox4);
mb[5] = RD_REG_WORD(&reg24->mailbox5);
+4 -3
View File
@@ -621,11 +621,12 @@ static void qla_nvme_remoteport_delete(struct nvme_fc_remote_port *rport)
}
static struct nvme_fc_port_template qla_nvme_fc_transport = {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0) && \
LINUX_VERSION_CODE < KERNEL_VERSION(5, 7, 0)
#if 0
/*
* See also commit 863fbae929c7 ("nvme_fc: add module to ops template
* to allow module references").
* to allow module references"). See also commit 8c5c66052920
* ("nvme-fc: Revert "add module to ops template to allow module
* references"") # v5.7-rc1.
*/
.module = THIS_MODULE,
#endif
+6 -23
View File
@@ -48,6 +48,11 @@ static int apidev_major;
*/
struct kmem_cache *srb_cachep;
int ql2xfulldump_on_mpifail;
module_param(ql2xfulldump_on_mpifail, int, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(ql2xfulldump_on_mpifail,
"Set this to take full dump on MPI hang.");
/*
* CT6 CTX allocation cache
*/
@@ -2564,6 +2569,7 @@ static struct isp_operations qla27xx_isp_ops = {
.read_nvram = NULL,
.write_nvram = NULL,
.fw_dump = qla27xx_fwdump,
.mpi_fw_dump = qla27xx_mpi_fwdump,
.beacon_on = qla24xx_beacon_on,
.beacon_off = qla24xx_beacon_off,
.beacon_blink = qla83xx_beacon_blink,
@@ -3983,19 +3989,6 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport,
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
}
/*
* qla2x00_mark_all_devices_lost
* Updates fcport state when device goes offline.
*
* Input:
* ha = adapter block pointer.
* fcport = port structure pointer.
*
* Return:
* None.
*
* Context:
*/
void
qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha)
{
@@ -4007,16 +4000,6 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha)
list_for_each_entry(fcport, &vha->vp_fcports, list) {
fcport->scan_state = 0;
qlt_schedule_sess_for_deletion(fcport);
if (vha->vp_idx != 0 && vha->vp_idx != fcport->vha->vp_idx)
continue;
/*
* No point in marking the device as lost, if the device is
* already DEAD.
*/
if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD)
continue;
}
}
+98 -21
View File
@@ -12,6 +12,33 @@
#define IOBASE(vha) IOBAR(ISPREG(vha))
#define INVALID_ENTRY ((struct qla27xx_fwdt_entry *)0xffffffffffffffffUL)
/* hardware_lock assumed held. */
static void
qla27xx_write_remote_reg(struct scsi_qla_host *vha,
u32 addr, u32 data)
{
char *reg = (char *)ISPREG(vha);
ql_dbg(ql_dbg_misc, vha, 0xd300,
"%s: addr/data = %xh/%xh\n", __func__, addr, data);
WRT_REG_DWORD(reg + IOBASE(vha), 0x40);
WRT_REG_DWORD(reg + 0xc4, data);
WRT_REG_DWORD(reg + 0xc0, addr);
}
void
qla27xx_reset_mpi(scsi_qla_host_t *vha)
{
ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd301,
"Entered %s.\n", __func__);
qla27xx_write_remote_reg(vha, 0x104050, 0x40004);
qla27xx_write_remote_reg(vha, 0x10405c, 0x4);
vha->hw->stat.num_mpi_reset++;
}
static inline void
qla27xx_insert16(uint16_t value, void *buf, ulong *len)
{
@@ -997,6 +1024,62 @@ qla27xx_fwdt_template_valid(void *p)
return true;
}
void
qla27xx_mpi_fwdump(scsi_qla_host_t *vha, int hardware_locked)
{
ulong flags = 0;
bool need_mpi_reset = 1;
#ifndef __CHECKER__
if (!hardware_locked)
spin_lock_irqsave(&vha->hw->hardware_lock, flags);
#endif
if (!vha->hw->mpi_fw_dump) {
ql_log(ql_log_warn, vha, 0x02f3, "-> mpi_fwdump no buffer\n");
} else if (vha->hw->mpi_fw_dumped) {
ql_log(ql_log_warn, vha, 0x02f4,
"-> MPI firmware already dumped (%p) -- ignoring request\n",
vha->hw->mpi_fw_dump);
} else {
struct fwdt *fwdt = &vha->hw->fwdt[1];
ulong len;
void *buf = vha->hw->mpi_fw_dump;
ql_log(ql_log_warn, vha, 0x02f5, "-> fwdt1 running...\n");
if (!fwdt->template) {
ql_log(ql_log_warn, vha, 0x02f6,
"-> fwdt1 no template\n");
goto bailout;
}
len = qla27xx_execute_fwdt_template(vha, fwdt->template, buf);
if (len == 0) {
goto bailout;
} else if (len != fwdt->dump_size) {
ql_log(ql_log_warn, vha, 0x02f7,
"-> fwdt1 fwdump residual=%+ld\n",
fwdt->dump_size - len);
} else {
need_mpi_reset = 0;
}
vha->hw->mpi_fw_dump_len = len;
vha->hw->mpi_fw_dumped = 1;
ql_log(ql_log_warn, vha, 0x02f8,
"-> MPI firmware dump saved to buffer (%lu/%p)\n",
vha->host_no, vha->hw->mpi_fw_dump);
qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP);
}
bailout:
if (need_mpi_reset)
qla27xx_reset_mpi(vha);
#ifndef __CHECKER__
if (!hardware_locked)
spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
#endif
}
void
qla27xx_fwdump(scsi_qla_host_t *vha, int hardware_locked)
{
@@ -1015,30 +1098,25 @@ qla27xx_fwdump(scsi_qla_host_t *vha, int hardware_locked)
vha->hw->fw_dump);
} else {
struct fwdt *fwdt = vha->hw->fwdt;
uint j;
ulong len;
void *buf = vha->hw->fw_dump;
uint count = vha->hw->fw_dump_mpi ? 2 : 1;
for (j = 0; j < count; j++, fwdt++, buf += len) {
ql_log(ql_log_warn, vha, 0xd011,
"-> fwdt%u running...\n", j);
if (!fwdt->template) {
ql_log(ql_log_warn, vha, 0xd012,
"-> fwdt%u no template\n", j);
break;
}
len = qla27xx_execute_fwdt_template(vha,
fwdt->template, buf);
if (len == 0) {
goto bailout;
} else if (len != fwdt->dump_size) {
ql_log(ql_log_warn, vha, 0xd013,
"-> fwdt%u fwdump residual=%+ld\n",
j, fwdt->dump_size - len);
}
ql_log(ql_log_warn, vha, 0xd011, "-> fwdt0 running...\n");
if (!fwdt->template) {
ql_log(ql_log_warn, vha, 0xd012,
"-> fwdt0 no template\n");
goto bailout;
}
vha->hw->fw_dump_len = buf - (void *)vha->hw->fw_dump;
len = qla27xx_execute_fwdt_template(vha, fwdt->template, buf);
if (len == 0) {
goto bailout;
} else if (len != fwdt->dump_size) {
ql_log(ql_log_warn, vha, 0xd013,
"-> fwdt0 fwdump residual=%+ld\n",
fwdt->dump_size - len);
}
vha->hw->fw_dump_len = len;
vha->hw->fw_dumped = 1;
ql_log(ql_log_warn, vha, 0xd015,
@@ -1048,7 +1126,6 @@ qla27xx_fwdump(scsi_qla_host_t *vha, int hardware_locked)
}
bailout:
vha->hw->fw_dump_mpi = 0;
#ifndef __CHECKER__
if (!hardware_locked)
spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
+44
View File
@@ -0,0 +1,44 @@
/* SPDX-License-Identifier: GPL-2.0 */
#if !defined(_TRACE_QLA_H_) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_QLA_H_
#include <linux/tracepoint.h>
#undef TRACE_SYSTEM
#define TRACE_SYSTEM qla
#define QLA_MSG_MAX 256
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
DECLARE_EVENT_CLASS(qla_log_event,
TP_PROTO(const char *buf,
struct va_format *vaf),
TP_ARGS(buf, vaf),
TP_STRUCT__entry(
__string(buf, buf)
__dynamic_array(char, msg, QLA_MSG_MAX)
),
TP_fast_assign(
__assign_str(buf, buf);
vsnprintf(__get_str(msg), QLA_MSG_MAX, vaf->fmt, *vaf->va);
),
TP_printk("%s %s", __get_str(buf), __get_str(msg))
);
DEFINE_EVENT(qla_log_event, ql_dbg_log,
TP_PROTO(const char *buf, struct va_format *vaf),
TP_ARGS(buf, vaf)
);
#pragma GCC diagnostic pop
#endif /* _TRACE_QLA_H */
#define TRACE_INCLUDE_FILE qla
#include <trace/define_trace.h>