From: James Smart Date: Wed, 18 Nov 2009 20:40:23 +0000 (-0500) Subject: [SCSI] lpfc 8.3.6 : Fix AER issues X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=891478a2442d8d0077651bc8316afaec8d85dd4d;p=mv-sheeva.git [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: James Smart Signed-off-by: James Bottomley --- diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index d55befb7cf4..75523603b91 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -2835,6 +2835,9 @@ lpfc_aer_support_store(struct device *dev, struct device_attribute *attr, 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) @@ -2851,10 +2854,11 @@ lpfc_aer_support_store(struct device *dev, struct device_attribute *attr, 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)) { @@ -2866,10 +2870,11 @@ lpfc_aer_support_store(struct device *dev, struct device_attribute *attr, 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; @@ -2905,6 +2910,12 @@ lpfc_param_show(aer_support) 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; @@ -2913,6 +2924,7 @@ lpfc_aer_support_init(struct lpfc_hba *phba, int val) "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; } @@ -2948,18 +2960,23 @@ lpfc_aer_cleanup_state(struct device *dev, struct device_attribute *attr, 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, diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c old mode 100644 new mode 100755 index 3c06aa54a3e..4d7d8846b4d --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -4369,6 +4369,14 @@ lpfc_fcf_inuse(struct lpfc_hba *phba) 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); @@ -4465,7 +4473,7 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba) (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); diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 6932657d74a..93679f30a5a 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -7141,6 +7141,28 @@ lpfc_pci_resume_one_s3(struct pci_dev *pdev) 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. @@ -7156,7 +7178,7 @@ lpfc_sli_prep_dev_for_reset(struct lpfc_hba *phba) 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); @@ -7181,7 +7203,7 @@ static void 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 */ @@ -7214,7 +7236,8 @@ lpfc_io_error_detected_s3(struct pci_dev *pdev, pci_channel_state_t state) 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 */