aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2010-03-15 11:25:32 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-04-11 10:23:50 -0400
commite2af0d2ed86a2415b0562526601cf2d5cae5a96d (patch)
tree9b9ac26c14c82847f234c9e270362000630c8f33 /drivers
parent7a4702774381103e936cae09ec12301090c6c212 (diff)
[SCSI] lpfc 8.3.11: Fix AER uncorrectable non-fatal error handling
Only abort outstanding I/O to force the OS to retry failed I/Os for AER uncorrectable non-fatal errors instead of reseting the adapter. Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c50
1 files changed, 27 insertions, 23 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index feba3be90cb2..56421c714bf8 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -7764,21 +7764,23 @@ lpfc_pci_resume_one_s3(struct pci_dev *pdev)
7764 * @phba: pointer to lpfc hba data structure. 7764 * @phba: pointer to lpfc hba data structure.
7765 * 7765 *
7766 * This routine is called to prepare the SLI3 device for PCI slot recover. It 7766 * This routine is called to prepare the SLI3 device for PCI slot recover. It
7767 * aborts and stops all the on-going I/Os on the pci device. 7767 * aborts all the outstanding SCSI I/Os to the pci device.
7768 **/ 7768 **/
7769static void 7769static void
7770lpfc_sli_prep_dev_for_recover(struct lpfc_hba *phba) 7770lpfc_sli_prep_dev_for_recover(struct lpfc_hba *phba)
7771{ 7771{
7772 struct lpfc_sli *psli = &phba->sli;
7773 struct lpfc_sli_ring *pring;
7774
7772 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 7775 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
7773 "2723 PCI channel I/O abort preparing for recovery\n"); 7776 "2723 PCI channel I/O abort preparing for recovery\n");
7774 /* Prepare for bringing HBA offline */ 7777
7775 lpfc_offline_prep(phba); 7778 /*
7776 /* Clear sli active flag to prevent sysfs access to HBA */ 7779 * There may be errored I/Os through HBA, abort all I/Os on txcmplq
7777 spin_lock_irq(&phba->hbalock); 7780 * and let the SCSI mid-layer to retry them to recover.
7778 phba->sli.sli_flag &= ~LPFC_SLI_ACTIVE; 7781 */
7779 spin_unlock_irq(&phba->hbalock); 7782 pring = &psli->ring[psli->fcp_ring];
7780 /* Stop and flush all I/Os and bring HBA offline */ 7783 lpfc_sli_abort_iocb_ring(phba, pring);
7781 lpfc_offline(phba);
7782} 7784}
7783 7785
7784/** 7786/**
@@ -7792,21 +7794,20 @@ lpfc_sli_prep_dev_for_recover(struct lpfc_hba *phba)
7792static void 7794static void
7793lpfc_sli_prep_dev_for_reset(struct lpfc_hba *phba) 7795lpfc_sli_prep_dev_for_reset(struct lpfc_hba *phba)
7794{ 7796{
7795 struct lpfc_sli *psli = &phba->sli;
7796 struct lpfc_sli_ring *pring;
7797
7798 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 7797 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
7799 "2710 PCI channel disable preparing for reset\n"); 7798 "2710 PCI channel disable preparing for reset\n");
7799
7800 /* Block all SCSI devices' I/Os on the host */
7801 lpfc_scsi_dev_block(phba);
7802
7803 /* stop all timers */
7804 lpfc_stop_hba_timers(phba);
7805
7800 /* Disable interrupt and pci device */ 7806 /* Disable interrupt and pci device */
7801 lpfc_sli_disable_intr(phba); 7807 lpfc_sli_disable_intr(phba);
7802 pci_disable_device(phba->pcidev); 7808 pci_disable_device(phba->pcidev);
7803 /* 7809 /* Flush all driver's outstanding SCSI I/Os as we are to reset */
7804 * There may be I/Os dropped by the firmware. 7810 lpfc_sli_flush_fcp_rings(phba);
7805 * Error iocb (I/O) on txcmplq and let the SCSI layer
7806 * retry it after re-establishing link.
7807 */
7808 pring = &psli->ring[psli->fcp_ring];
7809 lpfc_sli_abort_iocb_ring(phba, pring);
7810} 7811}
7811 7812
7812/** 7813/**
@@ -7822,6 +7823,12 @@ lpfc_prep_dev_for_perm_failure(struct lpfc_hba *phba)
7822{ 7823{
7823 lpfc_printf_log(phba, KERN_ERR, LOG_INIT, 7824 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
7824 "2711 PCI channel permanent disable for failure\n"); 7825 "2711 PCI channel permanent disable for failure\n");
7826 /* Block all SCSI devices' I/Os on the host */
7827 lpfc_scsi_dev_block(phba);
7828
7829 /* stop all timers */
7830 lpfc_stop_hba_timers(phba);
7831
7825 /* Clean up all driver's outstanding SCSI I/Os */ 7832 /* Clean up all driver's outstanding SCSI I/Os */
7826 lpfc_sli_flush_fcp_rings(phba); 7833 lpfc_sli_flush_fcp_rings(phba);
7827} 7834}
@@ -7850,9 +7857,6 @@ lpfc_io_error_detected_s3(struct pci_dev *pdev, pci_channel_state_t state)
7850 struct Scsi_Host *shost = pci_get_drvdata(pdev); 7857 struct Scsi_Host *shost = pci_get_drvdata(pdev);
7851 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; 7858 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
7852 7859
7853 /* Block all SCSI devices' I/Os on the host */
7854 lpfc_scsi_dev_block(phba);
7855
7856 switch (state) { 7860 switch (state) {
7857 case pci_channel_io_normal: 7861 case pci_channel_io_normal:
7858 /* Non-fatal error, prepare for recovery */ 7862 /* Non-fatal error, prepare for recovery */
@@ -7959,7 +7963,7 @@ lpfc_io_resume_s3(struct pci_dev *pdev)
7959 struct Scsi_Host *shost = pci_get_drvdata(pdev); 7963 struct Scsi_Host *shost = pci_get_drvdata(pdev);
7960 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; 7964 struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
7961 7965
7962 /* Bring the device online */ 7966 /* Bring device online, it will be no-op for non-fatal error resume */
7963 lpfc_online(phba); 7967 lpfc_online(phba);
7964 7968
7965 /* Clean up Advanced Error Reporting (AER) if needed */ 7969 /* Clean up Advanced Error Reporting (AER) if needed */