From def9c7a994f194377a23e687e6fd39b46c3ce631 Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 21 Dec 2009 17:02:28 -0500 Subject: [SCSI] lpfc 8.3.7: Fix hardware/SLI relates issues Fix hardware/SLI relates issues: - Fix CNA uses more than one EQ when in INTx interrupt mode. - Fix driver tries to process failed read FCF record mailbox request. - Fix allocating single receive buffer breaks FCoE receive queue. - Support new read FCF record mailbox error case. Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_init.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/scsi/lpfc/lpfc_init.c') diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index d4da6bdd0e73..7083ef3b3878 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -7507,6 +7507,9 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) error = -ENODEV; goto out_free_sysfs_attr; } + /* Default to single FCP EQ for non-MSI-X */ + if (phba->intr_type != MSIX) + phba->cfg_fcp_eq_count = 1; /* Set up SLI-4 HBA */ if (lpfc_sli4_hba_setup(phba)) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, -- cgit v1.2.3 From aacc20e35edfb86cf66c5ee8d9f3d06a98362fd1 Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 21 Dec 2009 17:02:51 -0500 Subject: [SCSI] lpfc 8.3.7: Fix SCSI protocol related errors. Fix SCSI protocol related errors: - Avoid I/O failures during EEH and HBA/CNA reset by correcting when we block the targets on the adapter. Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_hbadisc.c | 4 ++++ drivers/scsi/lpfc/lpfc_init.c | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers/scsi/lpfc/lpfc_init.c') diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index f40b9609f6e4..1c2737293eb5 100755 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -747,6 +747,10 @@ lpfc_linkdown(struct lpfc_hba *phba) if (phba->link_state == LPFC_LINK_DOWN) return 0; + + /* Block all SCSI stack I/Os */ + lpfc_scsi_dev_block(phba); + spin_lock_irq(&phba->hbalock); phba->fcf.fcf_flag &= ~(FCF_AVAILABLE | FCF_DISCOVERED); if (phba->link_state > LPFC_LINK_DOWN) { diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 7083ef3b3878..974ea6d85efe 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -7226,8 +7226,6 @@ lpfc_prep_dev_for_perm_failure(struct lpfc_hba *phba) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "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 */ lpfc_sli_flush_fcp_rings(phba); } @@ -7256,6 +7254,9 @@ lpfc_io_error_detected_s3(struct pci_dev *pdev, pci_channel_state_t state) struct Scsi_Host *shost = pci_get_drvdata(pdev); struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba; + /* Block all SCSI devices' I/Os on the host */ + lpfc_scsi_dev_block(phba); + switch (state) { case pci_channel_io_normal: /* Non-fatal error, prepare for recovery */ -- cgit v1.2.3 From 9795724476860069ce183ead59d0a5958f882037 Mon Sep 17 00:00:00 2001 From: James Smart Date: Mon, 21 Dec 2009 17:03:15 -0500 Subject: [SCSI] lpfc 8.3.7: Fix discovery failures. Fix discovery failures: - Move all accesses to the fc_flag field inside the host lock. - Restore link state after going through linkdown processing for FCF DEAD event. Signed-off-by: James Smart Signed-off-by: James Bottomley --- drivers/scsi/lpfc/lpfc_els.c | 2 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 6 ++++++ drivers/scsi/lpfc/lpfc_init.c | 6 +++++- drivers/scsi/lpfc/lpfc_vport.c | 2 ++ 4 files changed, 14 insertions(+), 2 deletions(-) (limited to 'drivers/scsi/lpfc/lpfc_init.c') diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index bb2e43a9e96c..2cc39684ce97 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -4142,8 +4142,8 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, spin_lock_irq(shost->host_lock); if (vport->fc_rscn_flush) { /* Another thread is walking fc_rscn_id_list on this vport */ - spin_unlock_irq(shost->host_lock); vport->fc_flag |= FC_RSCN_DISCOVERY; + spin_unlock_irq(shost->host_lock); /* Send back ACC */ lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); return 0; diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index 1c2737293eb5..2445e399fd60 100755 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1708,7 +1708,9 @@ lpfc_init_vpi_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) lpfc_vport_set_state(vport, FC_VPORT_FAILED); return; } + spin_lock_irq(&phba->hbalock); vport->fc_flag &= ~FC_VPORT_NEEDS_INIT_VPI; + spin_unlock_irq(&phba->hbalock); if (phba->link_flag & LS_NPIV_FAB_SUPPORTED) lpfc_initial_fdisc(vport); @@ -2269,8 +2271,10 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) mb->mbxStatus); break; } + spin_lock_irq(&phba->hbalock); vport->vpi_state &= ~LPFC_VPI_REGISTERED; vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; + spin_unlock_irq(&phba->hbalock); vport->unreg_vpi_cmpl = VPORT_OK; mempool_free(pmb, phba->mbox_mem_pool); /* @@ -4486,8 +4490,10 @@ 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]); + spin_lock_irq(&phba->hbalock); vports[i]->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED; + spin_unlock_irq(&phba->hbalock); } lpfc_destroy_vport_work_array(phba, vports); diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 974ea6d85efe..b8eb1b6e5e77 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -3006,6 +3006,7 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, struct lpfc_vport *vport; struct lpfc_nodelist *ndlp; struct Scsi_Host *shost; + uint32_t link_state; phba->fc_eventTag = acqe_fcoe->event_tag; phba->fcoe_eventtag = acqe_fcoe->event_tag; @@ -3052,9 +3053,12 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba, break; /* * Currently, driver support only one FCF - so treat this as - * a link down. + * a link down, but save the link state because we don't want + * it to be changed to Link Down unless it is already down. */ + link_state = phba->link_state; lpfc_linkdown(phba); + phba->link_state = link_state; /* Unregister FCF if no devices connected to it */ lpfc_unregister_unused_fcf(phba); break; diff --git a/drivers/scsi/lpfc/lpfc_vport.c b/drivers/scsi/lpfc/lpfc_vport.c index c3a70c4c9433..e3c7fa642306 100644 --- a/drivers/scsi/lpfc/lpfc_vport.c +++ b/drivers/scsi/lpfc/lpfc_vport.c @@ -512,8 +512,10 @@ enable_vport(struct fc_vport *fc_vport) return VPORT_OK; } + spin_lock_irq(&phba->hbalock); vport->load_flag |= FC_LOADING; vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; + spin_unlock_irq(&phba->hbalock); /* Use the Physical nodes Fabric NDLP to determine if the link is * up and ready to FDISC. -- cgit v1.2.3