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: James Smart <james.smart@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
struct lpfc_hba *phba = vport->phba;
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]))
return -EINVAL;
if (sscanf(buf, "%i", &val) != 1)
phba->cfg_aer_support = 0;
rc = strlen(buf);
} else
- rc = -EINVAL;
- } else
+ rc = -EPERM;
+ } else {
phba->cfg_aer_support = 0;
- rc = strlen(buf);
+ rc = strlen(buf);
+ }
break;
case 1:
if (!(phba->hba_flag & HBA_AER_ENABLED)) {
phba->cfg_aer_support = 1;
rc = strlen(buf);
} else
- rc = -EINVAL;
- } else
+ rc = -EPERM;
+ } else {
phba->cfg_aer_support = 1;
- rc = strlen(buf);
+ rc = strlen(buf);
+ }
break;
default:
rc = -EINVAL;
static int
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) {
phba->cfg_aer_support = val;
return 0;
"2712 lpfc_aer_support attribute value %d out "
"of range, allowed values are 0|1, setting it "
"to default value of 1\n", val);
+ /* By default, try to enable AER on a device */
phba->cfg_aer_support = 1;
return -EINVAL;
}
struct lpfc_hba *phba = vport->phba;
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]))
return -EINVAL;
if (sscanf(buf, "%i", &val) != 1)
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);
if (rc == 0)
return strlen(buf);
else
- return -EINVAL;
+ return -EPERM;
}
static DEVICE_ATTR(lpfc_aer_state_cleanup, S_IWUSR, NULL,
ret = 1;
spin_unlock_irq(shost->host_lock);
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);
(phba->sli3_options & LPFC_SLI3_NPIV_ENABLED))
for (i = 0; i <= phba->max_vports && vports[i] != NULL; 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;
}
lpfc_destroy_vport_work_array(phba, vports);
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
* @phba: pointer to lpfc hba data structure.
struct lpfc_sli_ring *pring;
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 */
lpfc_sli_disable_intr(phba);
pci_disable_device(phba->pcidev);
lpfc_prep_dev_for_perm_failure(struct lpfc_hba *phba)
{
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 */
lpfc_scsi_dev_block(phba);
/* Clean up all driver's outstanding SCSI I/Os */
switch (state) {
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;
case pci_channel_io_frozen:
/* Fatal error, prepare for slot reset */