|
Daniel Wagner |
cc5f26 |
From: James Smart <jsmart2021@gmail.com>
|
|
Daniel Wagner |
cc5f26 |
Date: Fri, 3 Dec 2021 16:26:40 -0800
|
|
Daniel Wagner |
cc5f26 |
Subject: scsi: lpfc: Trigger SLI4 firmware dump before doing driver cleanup
|
|
Daniel Wagner |
cc5f26 |
Patch-mainline: Queued in subsystem maintainer repository
|
|
Daniel Wagner |
cc5f26 |
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi.git
|
|
Daniel Wagner |
cc5f26 |
Git-commit: 7dd2e2a923173d637c272e483966be8e96a72b64
|
|
Daniel Wagner |
cc5f26 |
References: bsc1192145
|
|
Daniel Wagner |
cc5f26 |
|
|
Daniel Wagner |
cc5f26 |
Extraneous teardown routines are present in the firmware dump path causing
|
|
Daniel Wagner |
cc5f26 |
altered states in firmware captures.
|
|
Daniel Wagner |
cc5f26 |
|
|
Daniel Wagner |
cc5f26 |
When a firmware dump is requested via sysfs, trigger the dump immediately
|
|
Daniel Wagner |
cc5f26 |
without tearing down structures and changing adapter state.
|
|
Daniel Wagner |
cc5f26 |
|
|
Daniel Wagner |
cc5f26 |
The driver shall rely on pre-existing firmware error state clean up
|
|
Daniel Wagner |
cc5f26 |
handlers to restore the adapter.
|
|
Daniel Wagner |
cc5f26 |
|
|
Daniel Wagner |
cc5f26 |
Link: https://lore.kernel.org/r/20211204002644.116455-6-jsmart2021@gmail.com
|
|
Daniel Wagner |
cc5f26 |
Co-developed-by: Justin Tee <justin.tee@broadcom.com>
|
|
Daniel Wagner |
cc5f26 |
Signed-off-by: Justin Tee <justin.tee@broadcom.com>
|
|
Daniel Wagner |
cc5f26 |
Signed-off-by: James Smart <jsmart2021@gmail.com>
|
|
Daniel Wagner |
cc5f26 |
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
|
|
Daniel Wagner |
cc5f26 |
Acked-by: Daniel Wagner <dwagner@suse.de>
|
|
Daniel Wagner |
cc5f26 |
---
|
|
Daniel Wagner |
cc5f26 |
drivers/scsi/lpfc/lpfc.h | 2 -
|
|
Daniel Wagner |
cc5f26 |
drivers/scsi/lpfc/lpfc_attr.c | 62 +++++++++++++++++++++++++--------------
|
|
Daniel Wagner |
cc5f26 |
drivers/scsi/lpfc/lpfc_hbadisc.c | 8 ++++-
|
|
Daniel Wagner |
cc5f26 |
drivers/scsi/lpfc/lpfc_sli.c | 6 ---
|
|
Daniel Wagner |
cc5f26 |
4 files changed, 48 insertions(+), 30 deletions(-)
|
|
Daniel Wagner |
cc5f26 |
|
|
Daniel Wagner |
cc5f26 |
--- a/drivers/scsi/lpfc/lpfc.h
|
|
Daniel Wagner |
cc5f26 |
+++ b/drivers/scsi/lpfc/lpfc.h
|
|
Daniel Wagner |
cc5f26 |
@@ -930,7 +930,6 @@ struct lpfc_hba {
|
|
Daniel Wagner |
cc5f26 |
#define HBA_DEVLOSS_TMO 0x2000 /* HBA in devloss timeout */
|
|
Daniel Wagner |
cc5f26 |
#define HBA_RRQ_ACTIVE 0x4000 /* process the rrq active list */
|
|
Daniel Wagner |
cc5f26 |
#define HBA_IOQ_FLUSH 0x8000 /* FCP/NVME I/O queues being flushed */
|
|
Daniel Wagner |
cc5f26 |
-#define HBA_FW_DUMP_OP 0x10000 /* Skips fn reset before FW dump */
|
|
Daniel Wagner |
cc5f26 |
#define HBA_RECOVERABLE_UE 0x20000 /* Firmware supports recoverable UE */
|
|
Daniel Wagner |
cc5f26 |
#define HBA_FORCED_LINK_SPEED 0x40000 /*
|
|
Daniel Wagner |
cc5f26 |
* Firmware supports Forced Link Speed
|
|
Daniel Wagner |
cc5f26 |
@@ -947,6 +946,7 @@ struct lpfc_hba {
|
|
Daniel Wagner |
cc5f26 |
#define HBA_HBEAT_TMO 0x8000000 /* HBEAT initiated after timeout */
|
|
Daniel Wagner |
cc5f26 |
#define HBA_FLOGI_OUTSTANDING 0x10000000 /* FLOGI is outstanding */
|
|
Daniel Wagner |
cc5f26 |
|
|
Daniel Wagner |
cc5f26 |
+ struct completion *fw_dump_cmpl; /* cmpl event tracker for fw_dump */
|
|
Daniel Wagner |
cc5f26 |
uint32_t fcp_ring_in_use; /* When polling test if intr-hndlr active*/
|
|
Daniel Wagner |
cc5f26 |
struct lpfc_dmabuf slim2p;
|
|
Daniel Wagner |
cc5f26 |
|
|
Daniel Wagner |
cc5f26 |
--- a/drivers/scsi/lpfc/lpfc_attr.c
|
|
Daniel Wagner |
cc5f26 |
+++ b/drivers/scsi/lpfc/lpfc_attr.c
|
|
Daniel Wagner |
cc5f26 |
@@ -1712,25 +1712,25 @@ lpfc_sli4_pdev_reg_request(struct lpfc_h
|
|
Daniel Wagner |
cc5f26 |
before_fc_flag = phba->pport->fc_flag;
|
|
Daniel Wagner |
cc5f26 |
sriov_nr_virtfn = phba->cfg_sriov_nr_virtfn;
|
|
Daniel Wagner |
cc5f26 |
|
|
Daniel Wagner |
cc5f26 |
- /* Disable SR-IOV virtual functions if enabled */
|
|
Daniel Wagner |
cc5f26 |
- if (phba->cfg_sriov_nr_virtfn) {
|
|
Daniel Wagner |
cc5f26 |
- pci_disable_sriov(pdev);
|
|
Daniel Wagner |
cc5f26 |
- phba->cfg_sriov_nr_virtfn = 0;
|
|
Daniel Wagner |
cc5f26 |
- }
|
|
Daniel Wagner |
cc5f26 |
+ if (opcode == LPFC_FW_DUMP) {
|
|
Daniel Wagner |
cc5f26 |
+ init_completion(&online_compl);
|
|
Daniel Wagner |
cc5f26 |
+ phba->fw_dump_cmpl = &online_compl;
|
|
Daniel Wagner |
cc5f26 |
+ } else {
|
|
Daniel Wagner |
cc5f26 |
+ /* Disable SR-IOV virtual functions if enabled */
|
|
Daniel Wagner |
cc5f26 |
+ if (phba->cfg_sriov_nr_virtfn) {
|
|
Daniel Wagner |
cc5f26 |
+ pci_disable_sriov(pdev);
|
|
Daniel Wagner |
cc5f26 |
+ phba->cfg_sriov_nr_virtfn = 0;
|
|
Daniel Wagner |
cc5f26 |
+ }
|
|
Daniel Wagner |
cc5f26 |
|
|
Daniel Wagner |
cc5f26 |
- if (opcode == LPFC_FW_DUMP)
|
|
Daniel Wagner |
cc5f26 |
- phba->hba_flag |= HBA_FW_DUMP_OP;
|
|
Daniel Wagner |
cc5f26 |
+ status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
|
|
Daniel Wagner |
cc5f26 |
|
|
Daniel Wagner |
cc5f26 |
- status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE);
|
|
Daniel Wagner |
cc5f26 |
+ if (status != 0)
|
|
Daniel Wagner |
cc5f26 |
+ return status;
|
|
Daniel Wagner |
cc5f26 |
|
|
Daniel Wagner |
cc5f26 |
- if (status != 0) {
|
|
Daniel Wagner |
cc5f26 |
- phba->hba_flag &= ~HBA_FW_DUMP_OP;
|
|
Daniel Wagner |
cc5f26 |
- return status;
|
|
Daniel Wagner |
cc5f26 |
+ /* wait for the device to be quiesced before firmware reset */
|
|
Daniel Wagner |
cc5f26 |
+ msleep(100);
|
|
Daniel Wagner |
cc5f26 |
}
|
|
Daniel Wagner |
cc5f26 |
|
|
Daniel Wagner |
cc5f26 |
- /* wait for the device to be quiesced before firmware reset */
|
|
Daniel Wagner |
cc5f26 |
- msleep(100);
|
|
Daniel Wagner |
cc5f26 |
-
|
|
Daniel Wagner |
cc5f26 |
reg_val = readl(phba->sli4_hba.conf_regs_memmap_p +
|
|
Daniel Wagner |
cc5f26 |
LPFC_CTL_PDEV_CTL_OFFSET);
|
|
Daniel Wagner |
cc5f26 |
|
|
Daniel Wagner |
cc5f26 |
@@ -1759,24 +1759,42 @@ lpfc_sli4_pdev_reg_request(struct lpfc_h
|
|
Daniel Wagner |
cc5f26 |
lpfc_printf_log(phba, KERN_ERR, LOG_SLI,
|
|
Daniel Wagner |
cc5f26 |
"3153 Fail to perform the requested "
|
|
Daniel Wagner |
cc5f26 |
"access: x%x\n", reg_val);
|
|
Daniel Wagner |
cc5f26 |
+ if (phba->fw_dump_cmpl)
|
|
Daniel Wagner |
cc5f26 |
+ phba->fw_dump_cmpl = NULL;
|
|
Daniel Wagner |
cc5f26 |
return rc;
|
|
Daniel Wagner |
cc5f26 |
}
|
|
Daniel Wagner |
cc5f26 |
|
|
Daniel Wagner |
cc5f26 |
/* keep the original port state */
|
|
Daniel Wagner |
cc5f26 |
- if (before_fc_flag & FC_OFFLINE_MODE)
|
|
Daniel Wagner |
cc5f26 |
- goto out;
|
|
Daniel Wagner |
cc5f26 |
-
|
|
Daniel Wagner |
cc5f26 |
- init_completion(&online_compl);
|
|
Daniel Wagner |
cc5f26 |
- job_posted = lpfc_workq_post_event(phba, &status, &online_compl,
|
|
Daniel Wagner |
cc5f26 |
- LPFC_EVT_ONLINE);
|
|
Daniel Wagner |
cc5f26 |
- if (!job_posted)
|
|
Daniel Wagner |
cc5f26 |
+ if (before_fc_flag & FC_OFFLINE_MODE) {
|
|
Daniel Wagner |
cc5f26 |
+ if (phba->fw_dump_cmpl)
|
|
Daniel Wagner |
cc5f26 |
+ phba->fw_dump_cmpl = NULL;
|
|
Daniel Wagner |
cc5f26 |
goto out;
|
|
Daniel Wagner |
cc5f26 |
+ }
|
|
Daniel Wagner |
cc5f26 |
|
|
Daniel Wagner |
cc5f26 |
- wait_for_completion(&online_compl);
|
|
Daniel Wagner |
cc5f26 |
+ /* Firmware dump will trigger an HA_ERATT event, and
|
|
Daniel Wagner |
cc5f26 |
+ * lpfc_handle_eratt_s4 routine already handles bringing the port back
|
|
Daniel Wagner |
cc5f26 |
+ * online.
|
|
Daniel Wagner |
cc5f26 |
+ */
|
|
Daniel Wagner |
cc5f26 |
+ if (opcode == LPFC_FW_DUMP) {
|
|
Daniel Wagner |
cc5f26 |
+ wait_for_completion(phba->fw_dump_cmpl);
|
|
Daniel Wagner |
cc5f26 |
+ } else {
|
|
Daniel Wagner |
cc5f26 |
+ init_completion(&online_compl);
|
|
Daniel Wagner |
cc5f26 |
+ job_posted = lpfc_workq_post_event(phba, &status, &online_compl,
|
|
Daniel Wagner |
cc5f26 |
+ LPFC_EVT_ONLINE);
|
|
Daniel Wagner |
cc5f26 |
+ if (!job_posted)
|
|
Daniel Wagner |
cc5f26 |
+ goto out;
|
|
Daniel Wagner |
cc5f26 |
|
|
Daniel Wagner |
cc5f26 |
+ wait_for_completion(&online_compl);
|
|
Daniel Wagner |
cc5f26 |
+ }
|
|
Daniel Wagner |
cc5f26 |
out:
|
|
Daniel Wagner |
cc5f26 |
/* in any case, restore the virtual functions enabled as before */
|
|
Daniel Wagner |
cc5f26 |
if (sriov_nr_virtfn) {
|
|
Daniel Wagner |
cc5f26 |
+ /* If fw_dump was performed, first disable to clean up */
|
|
Daniel Wagner |
cc5f26 |
+ if (opcode == LPFC_FW_DUMP) {
|
|
Daniel Wagner |
cc5f26 |
+ pci_disable_sriov(pdev);
|
|
Daniel Wagner |
cc5f26 |
+ phba->cfg_sriov_nr_virtfn = 0;
|
|
Daniel Wagner |
cc5f26 |
+ }
|
|
Daniel Wagner |
cc5f26 |
+
|
|
Daniel Wagner |
cc5f26 |
sriov_err =
|
|
Daniel Wagner |
cc5f26 |
lpfc_sli_probe_sriov_nr_virtfn(phba, sriov_nr_virtfn);
|
|
Daniel Wagner |
cc5f26 |
if (!sriov_err)
|
|
Daniel Wagner |
cc5f26 |
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
|
|
Daniel Wagner |
cc5f26 |
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
|
|
Daniel Wagner |
cc5f26 |
@@ -739,10 +739,16 @@ lpfc_work_done(struct lpfc_hba *phba)
|
|
Daniel Wagner |
cc5f26 |
if (phba->pci_dev_grp == LPFC_PCI_DEV_OC)
|
|
Daniel Wagner |
cc5f26 |
lpfc_sli4_post_async_mbox(phba);
|
|
Daniel Wagner |
cc5f26 |
|
|
Daniel Wagner |
cc5f26 |
- if (ha_copy & HA_ERATT)
|
|
Daniel Wagner |
cc5f26 |
+ if (ha_copy & HA_ERATT) {
|
|
Daniel Wagner |
cc5f26 |
/* Handle the error attention event */
|
|
Daniel Wagner |
cc5f26 |
lpfc_handle_eratt(phba);
|
|
Daniel Wagner |
cc5f26 |
|
|
Daniel Wagner |
cc5f26 |
+ if (phba->fw_dump_cmpl) {
|
|
Daniel Wagner |
cc5f26 |
+ complete(phba->fw_dump_cmpl);
|
|
Daniel Wagner |
cc5f26 |
+ phba->fw_dump_cmpl = NULL;
|
|
Daniel Wagner |
cc5f26 |
+ }
|
|
Daniel Wagner |
cc5f26 |
+ }
|
|
Daniel Wagner |
cc5f26 |
+
|
|
Daniel Wagner |
cc5f26 |
if (ha_copy & HA_MBATT)
|
|
Daniel Wagner |
cc5f26 |
lpfc_sli_handle_mb_event(phba);
|
|
Daniel Wagner |
cc5f26 |
|
|
Daniel Wagner |
cc5f26 |
--- a/drivers/scsi/lpfc/lpfc_sli.c
|
|
Daniel Wagner |
cc5f26 |
+++ b/drivers/scsi/lpfc/lpfc_sli.c
|
|
Daniel Wagner |
cc5f26 |
@@ -4911,12 +4911,6 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba
|
|
Daniel Wagner |
cc5f26 |
phba->fcf.fcf_flag = 0;
|
|
Daniel Wagner |
cc5f26 |
spin_unlock_irq(&phba->hbalock);
|
|
Daniel Wagner |
cc5f26 |
|
|
Daniel Wagner |
cc5f26 |
- /* SLI4 INTF 2: if FW dump is being taken skip INIT_PORT */
|
|
Daniel Wagner |
cc5f26 |
- if (phba->hba_flag & HBA_FW_DUMP_OP) {
|
|
Daniel Wagner |
cc5f26 |
- phba->hba_flag &= ~HBA_FW_DUMP_OP;
|
|
Daniel Wagner |
cc5f26 |
- return rc;
|
|
Daniel Wagner |
cc5f26 |
- }
|
|
Daniel Wagner |
cc5f26 |
-
|
|
Daniel Wagner |
cc5f26 |
/* Now physically reset the device */
|
|
Daniel Wagner |
cc5f26 |
lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
|
|
Daniel Wagner |
cc5f26 |
"0389 Performing PCI function reset!\n");
|