Commit 891478a2 authored by James Smart's avatar James Smart Committed by James Bottomley

[SCSI] lpfc 8.3.6 : Fix AER issues

Fix AER issues.
 - Made AER sysfs entry point return "Operation not permitted" to
   OneConnect HBAs
 - Stop and abort all I/Os on HBA for AER uncorrectable non-fatal error
   handling
Signed-off-by: default avatarJames Smart <james.smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@suse.de>
parent 5ffc266e
...@@ -2835,6 +2835,9 @@ lpfc_aer_support_store(struct device *dev, struct device_attribute *attr, ...@@ -2835,6 +2835,9 @@ lpfc_aer_support_store(struct device *dev, struct device_attribute *attr,
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
int val = 0, rc = -EINVAL; int val = 0, rc = -EINVAL;
/* AER not supported on OC devices yet */
if (phba->pci_dev_grp == LPFC_PCI_DEV_OC)
return -EPERM;
if (!isdigit(buf[0])) if (!isdigit(buf[0]))
return -EINVAL; return -EINVAL;
if (sscanf(buf, "%i", &val) != 1) if (sscanf(buf, "%i", &val) != 1)
...@@ -2851,10 +2854,11 @@ lpfc_aer_support_store(struct device *dev, struct device_attribute *attr, ...@@ -2851,10 +2854,11 @@ lpfc_aer_support_store(struct device *dev, struct device_attribute *attr,
phba->cfg_aer_support = 0; phba->cfg_aer_support = 0;
rc = strlen(buf); rc = strlen(buf);
} else } else
rc = -EINVAL; rc = -EPERM;
} else } else {
phba->cfg_aer_support = 0; phba->cfg_aer_support = 0;
rc = strlen(buf); rc = strlen(buf);
}
break; break;
case 1: case 1:
if (!(phba->hba_flag & HBA_AER_ENABLED)) { if (!(phba->hba_flag & HBA_AER_ENABLED)) {
...@@ -2866,10 +2870,11 @@ lpfc_aer_support_store(struct device *dev, struct device_attribute *attr, ...@@ -2866,10 +2870,11 @@ lpfc_aer_support_store(struct device *dev, struct device_attribute *attr,
phba->cfg_aer_support = 1; phba->cfg_aer_support = 1;
rc = strlen(buf); rc = strlen(buf);
} else } else
rc = -EINVAL; rc = -EPERM;
} else } else {
phba->cfg_aer_support = 1; phba->cfg_aer_support = 1;
rc = strlen(buf); rc = strlen(buf);
}
break; break;
default: default:
rc = -EINVAL; rc = -EINVAL;
...@@ -2905,6 +2910,12 @@ lpfc_param_show(aer_support) ...@@ -2905,6 +2910,12 @@ lpfc_param_show(aer_support)
static int static int
lpfc_aer_support_init(struct lpfc_hba *phba, int val) lpfc_aer_support_init(struct lpfc_hba *phba, int val)
{ {
/* AER not supported on OC devices yet */
if (phba->pci_dev_grp == LPFC_PCI_DEV_OC) {
phba->cfg_aer_support = 0;
return -EPERM;
}
if (val == 0 || val == 1) { if (val == 0 || val == 1) {
phba->cfg_aer_support = val; phba->cfg_aer_support = val;
return 0; return 0;
...@@ -2913,6 +2924,7 @@ lpfc_aer_support_init(struct lpfc_hba *phba, int val) ...@@ -2913,6 +2924,7 @@ lpfc_aer_support_init(struct lpfc_hba *phba, int val)
"2712 lpfc_aer_support attribute value %d out " "2712 lpfc_aer_support attribute value %d out "
"of range, allowed values are 0|1, setting it " "of range, allowed values are 0|1, setting it "
"to default value of 1\n", val); "to default value of 1\n", val);
/* By default, try to enable AER on a device */
phba->cfg_aer_support = 1; phba->cfg_aer_support = 1;
return -EINVAL; return -EINVAL;
} }
...@@ -2948,18 +2960,23 @@ lpfc_aer_cleanup_state(struct device *dev, struct device_attribute *attr, ...@@ -2948,18 +2960,23 @@ lpfc_aer_cleanup_state(struct device *dev, struct device_attribute *attr,
struct lpfc_hba *phba = vport->phba; struct lpfc_hba *phba = vport->phba;
int val, rc = -1; int val, rc = -1;
/* AER not supported on OC devices yet */
if (phba->pci_dev_grp == LPFC_PCI_DEV_OC)
return -EPERM;
if (!isdigit(buf[0])) if (!isdigit(buf[0]))
return -EINVAL; return -EINVAL;
if (sscanf(buf, "%i", &val) != 1) if (sscanf(buf, "%i", &val) != 1)
return -EINVAL; return -EINVAL;
if (val != 1)
return -EINVAL;
if (val == 1 && phba->hba_flag & HBA_AER_ENABLED) if (phba->hba_flag & HBA_AER_ENABLED)
rc = pci_cleanup_aer_uncorrect_error_status(phba->pcidev); rc = pci_cleanup_aer_uncorrect_error_status(phba->pcidev);
if (rc == 0) if (rc == 0)
return strlen(buf); return strlen(buf);
else else
return -EINVAL; return -EPERM;
} }
static DEVICE_ATTR(lpfc_aer_state_cleanup, S_IWUSR, NULL, static DEVICE_ATTR(lpfc_aer_state_cleanup, S_IWUSR, NULL,
......
...@@ -4369,6 +4369,14 @@ lpfc_fcf_inuse(struct lpfc_hba *phba) ...@@ -4369,6 +4369,14 @@ lpfc_fcf_inuse(struct lpfc_hba *phba)
ret = 1; ret = 1;
spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock);
goto out; goto out;
} else {
lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
"2624 RPI %x DID %x flg %x still "
"logged in\n",
ndlp->nlp_rpi, ndlp->nlp_DID,
ndlp->nlp_flag);
if (ndlp->nlp_flag & NLP_RPI_VALID)
ret = 1;
} }
} }
spin_unlock_irq(shost->host_lock); spin_unlock_irq(shost->host_lock);
...@@ -4465,7 +4473,7 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba) ...@@ -4465,7 +4473,7 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba)
(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED))
for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
lpfc_mbx_unreg_vpi(vports[i]); lpfc_mbx_unreg_vpi(vports[i]);
vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI; vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED; vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED;
} }
lpfc_destroy_vport_work_array(phba, vports); lpfc_destroy_vport_work_array(phba, vports);
......
...@@ -7141,6 +7141,28 @@ lpfc_pci_resume_one_s3(struct pci_dev *pdev) ...@@ -7141,6 +7141,28 @@ lpfc_pci_resume_one_s3(struct pci_dev *pdev)
return 0; return 0;
} }
/**
* lpfc_sli_prep_dev_for_recover - Prepare SLI3 device for pci slot recover
* @phba: pointer to lpfc hba data structure.
*
* This routine is called to prepare the SLI3 device for PCI slot recover. It
* aborts and stops all the on-going I/Os on the pci device.
**/
static void
lpfc_sli_prep_dev_for_recover(struct lpfc_hba *phba)
{
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"2723 PCI channel I/O abort preparing for recovery\n");
/* Prepare for bringing HBA offline */
lpfc_offline_prep(phba);
/* Clear sli active flag to prevent sysfs access to HBA */
spin_lock_irq(&phba->hbalock);
phba->sli.sli_flag &= ~LPFC_SLI_ACTIVE;
spin_unlock_irq(&phba->hbalock);
/* Stop and flush all I/Os and bring HBA offline */
lpfc_offline(phba);
}
/** /**
* lpfc_sli_prep_dev_for_reset - Prepare SLI3 device for pci slot reset * lpfc_sli_prep_dev_for_reset - Prepare SLI3 device for pci slot reset
* @phba: pointer to lpfc hba data structure. * @phba: pointer to lpfc hba data structure.
...@@ -7156,7 +7178,7 @@ lpfc_sli_prep_dev_for_reset(struct lpfc_hba *phba) ...@@ -7156,7 +7178,7 @@ lpfc_sli_prep_dev_for_reset(struct lpfc_hba *phba)
struct lpfc_sli_ring *pring; struct lpfc_sli_ring *pring;
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"2710 PCI channel I/O frozen\n"); "2710 PCI channel disable preparing for reset\n");
/* Disable interrupt and pci device */ /* Disable interrupt and pci device */
lpfc_sli_disable_intr(phba); lpfc_sli_disable_intr(phba);
pci_disable_device(phba->pcidev); pci_disable_device(phba->pcidev);
...@@ -7181,7 +7203,7 @@ static void ...@@ -7181,7 +7203,7 @@ static void
lpfc_prep_dev_for_perm_failure(struct lpfc_hba *phba) lpfc_prep_dev_for_perm_failure(struct lpfc_hba *phba)
{ {
lpfc_printf_log(phba, KERN_ERR, LOG_INIT, lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
"2711 PCI channel I/O permanent failure\n"); "2711 PCI channel permanent disable for failure\n");
/* Block all SCSI devices' I/Os on the host */ /* Block all SCSI devices' I/Os on the host */
lpfc_scsi_dev_block(phba); lpfc_scsi_dev_block(phba);
/* Clean up all driver's outstanding SCSI I/Os */ /* Clean up all driver's outstanding SCSI I/Os */
...@@ -7214,7 +7236,8 @@ lpfc_io_error_detected_s3(struct pci_dev *pdev, pci_channel_state_t state) ...@@ -7214,7 +7236,8 @@ lpfc_io_error_detected_s3(struct pci_dev *pdev, pci_channel_state_t state)
switch (state) { switch (state) {
case pci_channel_io_normal: case pci_channel_io_normal:
/* Non-fatal error, do nothing */ /* Non-fatal error, prepare for recovery */
lpfc_sli_prep_dev_for_recover(phba);
return PCI_ERS_RESULT_CAN_RECOVER; return PCI_ERS_RESULT_CAN_RECOVER;
case pci_channel_io_frozen: case pci_channel_io_frozen:
/* Fatal error, prepare for slot reset */ /* Fatal error, prepare for slot reset */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment