aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc
diff options
context:
space:
mode:
authorJames Smart <James.Smart@Emulex.Com>2009-11-18 15:40:23 -0500
committerJames Bottomley <James.Bottomley@suse.de>2009-12-04 13:01:51 -0500
commit891478a2442d8d0077651bc8316afaec8d85dd4d (patch)
tree9758bf87edbf4446ceb2fcce20fcebb1ae31fbfb /drivers/scsi/lpfc
parent5ffc266ee7a62741ebee89ede15049ec0f02fa75 (diff)
[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 <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/lpfc')
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c33
-rwxr-xr-x[-rw-r--r--]drivers/scsi/lpfc/lpfc_hbadisc.c10
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c29
3 files changed, 60 insertions, 12 deletions
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index d55befb7cf4c..75523603b91c 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,
2835 struct lpfc_hba *phba = vport->phba; 2835 struct lpfc_hba *phba = vport->phba;
2836 int val = 0, rc = -EINVAL; 2836 int val = 0, rc = -EINVAL;
2837 2837
2838 /* AER not supported on OC devices yet */
2839 if (phba->pci_dev_grp == LPFC_PCI_DEV_OC)
2840 return -EPERM;
2838 if (!isdigit(buf[0])) 2841 if (!isdigit(buf[0]))
2839 return -EINVAL; 2842 return -EINVAL;
2840 if (sscanf(buf, "%i", &val) != 1) 2843 if (sscanf(buf, "%i", &val) != 1)
@@ -2851,10 +2854,11 @@ lpfc_aer_support_store(struct device *dev, struct device_attribute *attr,
2851 phba->cfg_aer_support = 0; 2854 phba->cfg_aer_support = 0;
2852 rc = strlen(buf); 2855 rc = strlen(buf);
2853 } else 2856 } else
2854 rc = -EINVAL; 2857 rc = -EPERM;
2855 } else 2858 } else {
2856 phba->cfg_aer_support = 0; 2859 phba->cfg_aer_support = 0;
2857 rc = strlen(buf); 2860 rc = strlen(buf);
2861 }
2858 break; 2862 break;
2859 case 1: 2863 case 1:
2860 if (!(phba->hba_flag & HBA_AER_ENABLED)) { 2864 if (!(phba->hba_flag & HBA_AER_ENABLED)) {
@@ -2866,10 +2870,11 @@ lpfc_aer_support_store(struct device *dev, struct device_attribute *attr,
2866 phba->cfg_aer_support = 1; 2870 phba->cfg_aer_support = 1;
2867 rc = strlen(buf); 2871 rc = strlen(buf);
2868 } else 2872 } else
2869 rc = -EINVAL; 2873 rc = -EPERM;
2870 } else 2874 } else {
2871 phba->cfg_aer_support = 1; 2875 phba->cfg_aer_support = 1;
2872 rc = strlen(buf); 2876 rc = strlen(buf);
2877 }
2873 break; 2878 break;
2874 default: 2879 default:
2875 rc = -EINVAL; 2880 rc = -EINVAL;
@@ -2905,6 +2910,12 @@ lpfc_param_show(aer_support)
2905static int 2910static int
2906lpfc_aer_support_init(struct lpfc_hba *phba, int val) 2911lpfc_aer_support_init(struct lpfc_hba *phba, int val)
2907{ 2912{
2913 /* AER not supported on OC devices yet */
2914 if (phba->pci_dev_grp == LPFC_PCI_DEV_OC) {
2915 phba->cfg_aer_support = 0;
2916 return -EPERM;
2917 }
2918
2908 if (val == 0 || val == 1) { 2919 if (val == 0 || val == 1) {
2909 phba->cfg_aer_support = val; 2920 phba->cfg_aer_support = val;
2910 return 0; 2921 return 0;
@@ -2913,6 +2924,7 @@ lpfc_aer_support_init(struct lpfc_hba *phba, int val)
2913 "2712 lpfc_aer_support attribute value %d out " 2924 "2712 lpfc_aer_support attribute value %d out "
2914 "of range, allowed values are 0|1, setting it " 2925 "of range, allowed values are 0|1, setting it "
2915 "to default value of 1\n", val); 2926 "to default value of 1\n", val);
2927 /* By default, try to enable AER on a device */
2916 phba->cfg_aer_support = 1; 2928 phba->cfg_aer_support = 1;
2917 return -EINVAL; 2929 return -EINVAL;
2918} 2930}
@@ -2948,18 +2960,23 @@ lpfc_aer_cleanup_state(struct device *dev, struct device_attribute *attr,
2948 struct lpfc_hba *phba = vport->phba; 2960 struct lpfc_hba *phba = vport->phba;
2949 int val, rc = -1; 2961 int val, rc = -1;
2950 2962
2963 /* AER not supported on OC devices yet */
2964 if (phba->pci_dev_grp == LPFC_PCI_DEV_OC)
2965 return -EPERM;
2951 if (!isdigit(buf[0])) 2966 if (!isdigit(buf[0]))
2952 return -EINVAL; 2967 return -EINVAL;
2953 if (sscanf(buf, "%i", &val) != 1) 2968 if (sscanf(buf, "%i", &val) != 1)
2954 return -EINVAL; 2969 return -EINVAL;
2970 if (val != 1)
2971 return -EINVAL;
2955 2972
2956 if (val == 1 && phba->hba_flag & HBA_AER_ENABLED) 2973 if (phba->hba_flag & HBA_AER_ENABLED)
2957 rc = pci_cleanup_aer_uncorrect_error_status(phba->pcidev); 2974 rc = pci_cleanup_aer_uncorrect_error_status(phba->pcidev);
2958 2975
2959 if (rc == 0) 2976 if (rc == 0)
2960 return strlen(buf); 2977 return strlen(buf);
2961 else 2978 else
2962 return -EINVAL; 2979 return -EPERM;
2963} 2980}
2964 2981
2965static DEVICE_ATTR(lpfc_aer_state_cleanup, S_IWUSR, NULL, 2982static 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
index 3c06aa54a3e5..4d7d8846b4da 100644..100755
--- 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)
4369 ret = 1; 4369 ret = 1;
4370 spin_unlock_irq(shost->host_lock); 4370 spin_unlock_irq(shost->host_lock);
4371 goto out; 4371 goto out;
4372 } else {
4373 lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
4374 "2624 RPI %x DID %x flg %x still "
4375 "logged in\n",
4376 ndlp->nlp_rpi, ndlp->nlp_DID,
4377 ndlp->nlp_flag);
4378 if (ndlp->nlp_flag & NLP_RPI_VALID)
4379 ret = 1;
4372 } 4380 }
4373 } 4381 }
4374 spin_unlock_irq(shost->host_lock); 4382 spin_unlock_irq(shost->host_lock);
@@ -4465,7 +4473,7 @@ lpfc_unregister_unused_fcf(struct lpfc_hba *phba)
4465 (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED)) 4473 (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED))
4466 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { 4474 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
4467 lpfc_mbx_unreg_vpi(vports[i]); 4475 lpfc_mbx_unreg_vpi(vports[i]);
4468 vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI; 4476 vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
4469 vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED; 4477 vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED;
4470 } 4478 }
4471 lpfc_destroy_vport_work_array(phba, vports); 4479 lpfc_destroy_vport_work_array(phba, vports);
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 6932657d74ad..93679f30a5af 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -7142,6 +7142,28 @@ lpfc_pci_resume_one_s3(struct pci_dev *pdev)
7142} 7142}
7143 7143
7144/** 7144/**
7145 * lpfc_sli_prep_dev_for_recover - Prepare SLI3 device for pci slot recover
7146 * @phba: pointer to lpfc hba data structure.
7147 *
7148 * This routine is called to prepare the SLI3 device for PCI slot recover. It
7149 * aborts and stops all the on-going I/Os on the pci device.
7150 **/
7151static void
7152lpfc_sli_prep_dev_for_recover(struct lpfc_hba *phba)
7153{
7154 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
7155 "2723 PCI channel I/O abort preparing for recovery\n");
7156 /* Prepare for bringing HBA offline */
7157 lpfc_offline_prep(phba);
7158 /* Clear sli active flag to prevent sysfs access to HBA */
7159 spin_lock_irq(&phba->hbalock);
7160 phba->sli.sli_flag &= ~LPFC_SLI_ACTIVE;
7161 spin_unlock_irq(&phba->hbalock);
7162 /* Stop and flush all I/Os and bring HBA offline */
7163 lpfc_offline(phba);
7164}
7165
7166/**
7145 * lpfc_sli_prep_dev_for_reset - Prepare SLI3 device for pci slot reset 7167 * lpfc_sli_prep_dev_for_reset - Prepare SLI3 device for pci slot reset
7146 * @phba: pointer to lpfc hba data structure. 7168 * @phba: pointer to lpfc hba data structure.
7147 * 7169 *
@@ -7156,7 +7178,7 @@ lpfc_sli_prep_dev_for_reset(struct lpfc_hba *phba)
7156 struct lpfc_sli_ring *pring; 7178 struct lpfc_sli_ring *pring;
7157 7179
7158 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 7180 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
7159 "2710 PCI channel I/O frozen\n"); 7181 "2710 PCI channel disable preparing for reset\n");
7160 /* Disable interrupt and pci device */ 7182 /* Disable interrupt and pci device */
7161 lpfc_sli_disable_intr(phba); 7183 lpfc_sli_disable_intr(phba);
7162 pci_disable_device(phba->pcidev); 7184 pci_disable_device(phba->pcidev);
@@ -7181,7 +7203,7 @@ static void
7181lpfc_prep_dev_for_perm_failure(struct lpfc_hba *phba) 7203lpfc_prep_dev_for_perm_failure(struct lpfc_hba *phba)
7182{ 7204{
7183 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 7205 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
7184 "2711 PCI channel I/O permanent failure\n"); 7206 "2711 PCI channel permanent disable for failure\n");
7185 /* Block all SCSI devices' I/Os on the host */ 7207 /* Block all SCSI devices' I/Os on the host */
7186 lpfc_scsi_dev_block(phba); 7208 lpfc_scsi_dev_block(phba);
7187 /* Clean up all driver's outstanding SCSI I/Os */ 7209 /* 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 7236
7215 switch (state) { 7237 switch (state) {
7216 case pci_channel_io_normal: 7238 case pci_channel_io_normal:
7217 /* Non-fatal error, do nothing */ 7239 /* Non-fatal error, prepare for recovery */
7240 lpfc_sli_prep_dev_for_recover(phba);
7218 return PCI_ERS_RESULT_CAN_RECOVER; 7241 return PCI_ERS_RESULT_CAN_RECOVER;
7219 case pci_channel_io_frozen: 7242 case pci_channel_io_frozen:
7220 /* Fatal error, prepare for slot reset */ 7243 /* Fatal error, prepare for slot reset */