aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2010-10-22 11:05:36 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-10-25 17:35:36 -0400
commit5ac6b303834aa74855ecc3db98b4b1d9cad0de2f (patch)
tree62a3dc32a25d30dcdc4790151e1a01f51b431e9b
parent32622bdea031a5a6a6efd6dac9b317de46d5c6f8 (diff)
[SCSI] lpfc 8.3.18: FC/FCoE Discovery fixes
FC/FCoE Discovery fixes: - Call the lpfc_drain_txq only for SLI4 hba - In lpfc_cmpl_els_fdisc, fix code path that does not free IOCB. - Treated firmware matching FCF property with different index as error - Propagate error returns from lpfc_issue_els_flogi() - Refactored lpfc_unregister_unused_fcf() to create a post lpfc_dev_loss_tmo handler call for SLI-4 devices. Allows checking of fcf after last ndlp released so that fcf can be released if no longer in use. - Replaced individual FCF_XXXX_DISC flag clearing in lieu of aggregate FCF_DISCOVERY flag upon succesful completion of flogi. - Correct setting of altBbCredit value in sparams to correct issue with logins with remote loop-based devices. 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>
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c20
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c79
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c9
3 files changed, 58 insertions, 50 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index e6ca12f6c6cb..b16311d60c66 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -523,12 +523,6 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
523 spin_lock_irq(shost->host_lock); 523 spin_lock_irq(shost->host_lock);
524 vport->fc_flag |= FC_PUBLIC_LOOP; 524 vport->fc_flag |= FC_PUBLIC_LOOP;
525 spin_unlock_irq(shost->host_lock); 525 spin_unlock_irq(shost->host_lock);
526 } else {
527 /*
528 * If we are a N-port connected to a Fabric, fixup sparam's so
529 * logins to devices on remote loops work.
530 */
531 vport->fc_sparam.cmn.altBbCredit = 1;
532 } 526 }
533 527
534 vport->fc_myDID = irsp->un.ulpWord[4] & Mask_DID; 528 vport->fc_myDID = irsp->un.ulpWord[4] & Mask_DID;
@@ -1175,12 +1169,13 @@ lpfc_initial_flogi(struct lpfc_vport *vport)
1175 return 0; 1169 return 0;
1176 } 1170 }
1177 1171
1178 if (lpfc_issue_els_flogi(vport, ndlp, 0)) 1172 if (lpfc_issue_els_flogi(vport, ndlp, 0)) {
1179 /* This decrement of reference count to node shall kick off 1173 /* This decrement of reference count to node shall kick off
1180 * the release of the node. 1174 * the release of the node.
1181 */ 1175 */
1182 lpfc_nlp_put(ndlp); 1176 lpfc_nlp_put(ndlp);
1183 1177 return 0;
1178 }
1184 return 1; 1179 return 1;
1185} 1180}
1186 1181
@@ -1645,6 +1640,13 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
1645 memcpy(pcmd, &vport->fc_sparam, sizeof(struct serv_parm)); 1640 memcpy(pcmd, &vport->fc_sparam, sizeof(struct serv_parm));
1646 sp = (struct serv_parm *) pcmd; 1641 sp = (struct serv_parm *) pcmd;
1647 1642
1643 /*
1644 * If we are a N-port connected to a Fabric, fix-up paramm's so logins
1645 * to device on remote loops work.
1646 */
1647 if ((vport->fc_flag & FC_FABRIC) && !(vport->fc_flag & FC_PUBLIC_LOOP))
1648 sp->cmn.altBbCredit = 1;
1649
1648 if (sp->cmn.fcphLow < FC_PH_4_3) 1650 if (sp->cmn.fcphLow < FC_PH_4_3)
1649 sp->cmn.fcphLow = FC_PH_4_3; 1651 sp->cmn.fcphLow = FC_PH_4_3;
1650 1652
@@ -6452,7 +6454,7 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
6452 * to update the MAC address. 6454 * to update the MAC address.
6453 */ 6455 */
6454 lpfc_register_new_vport(phba, vport, ndlp); 6456 lpfc_register_new_vport(phba, vport, ndlp);
6455 return ; 6457 goto out;
6456 } 6458 }
6457 6459
6458 if (vport->fc_flag & FC_VPORT_NEEDS_INIT_VPI) 6460 if (vport->fc_flag & FC_VPORT_NEEDS_INIT_VPI)
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index a345dde16c86..0788bf670add 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -1803,6 +1803,16 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
1803 if ((phba->fcf.fcf_flag & FCF_IN_USE) && 1803 if ((phba->fcf.fcf_flag & FCF_IN_USE) &&
1804 lpfc_sli4_fcf_record_match(phba, &phba->fcf.current_rec, 1804 lpfc_sli4_fcf_record_match(phba, &phba->fcf.current_rec,
1805 new_fcf_record, LPFC_FCOE_IGNORE_VID)) { 1805 new_fcf_record, LPFC_FCOE_IGNORE_VID)) {
1806 if (bf_get(lpfc_fcf_record_fcf_index, new_fcf_record) !=
1807 phba->fcf.current_rec.fcf_indx) {
1808 lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
1809 "2862 FCF (x%x) matches property "
1810 "of in-use FCF (x%x)\n",
1811 bf_get(lpfc_fcf_record_fcf_index,
1812 new_fcf_record),
1813 phba->fcf.current_rec.fcf_indx);
1814 goto read_next_fcf;
1815 }
1806 /* 1816 /*
1807 * In case the current in-use FCF record becomes 1817 * In case the current in-use FCF record becomes
1808 * invalid/unavailable during FCF discovery that 1818 * invalid/unavailable during FCF discovery that
@@ -1844,22 +1854,29 @@ lpfc_mbx_cmpl_fcf_scan_read_fcf_rec(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
1844 if (phba->fcf.fcf_flag & FCF_IN_USE) { 1854 if (phba->fcf.fcf_flag & FCF_IN_USE) {
1845 if (lpfc_sli4_fcf_record_match(phba, &phba->fcf.current_rec, 1855 if (lpfc_sli4_fcf_record_match(phba, &phba->fcf.current_rec,
1846 new_fcf_record, vlan_id)) { 1856 new_fcf_record, vlan_id)) {
1847 phba->fcf.fcf_flag |= FCF_AVAILABLE; 1857 if (bf_get(lpfc_fcf_record_fcf_index, new_fcf_record) ==
1848 if (phba->fcf.fcf_flag & FCF_REDISC_PEND) 1858 phba->fcf.current_rec.fcf_indx) {
1849 /* Stop FCF redisc wait timer if pending */ 1859 phba->fcf.fcf_flag |= FCF_AVAILABLE;
1850 __lpfc_sli4_stop_fcf_redisc_wait_timer(phba); 1860 if (phba->fcf.fcf_flag & FCF_REDISC_PEND)
1851 else if (phba->fcf.fcf_flag & FCF_REDISC_FOV) 1861 /* Stop FCF redisc wait timer */
1852 /* If in fast failover, mark it's completed */ 1862 __lpfc_sli4_stop_fcf_redisc_wait_timer(
1853 phba->fcf.fcf_flag &= ~FCF_REDISC_FOV; 1863 phba);
1854 spin_unlock_irq(&phba->hbalock); 1864 else if (phba->fcf.fcf_flag & FCF_REDISC_FOV)
1855 lpfc_printf_log(phba, KERN_INFO, LOG_FIP, 1865 /* Fast failover, mark completed */
1856 "2836 The new FCF record (x%x) " 1866 phba->fcf.fcf_flag &= ~FCF_REDISC_FOV;
1857 "matches the in-use FCF record " 1867 spin_unlock_irq(&phba->hbalock);
1858 "(x%x)\n", 1868 lpfc_printf_log(phba, KERN_INFO, LOG_FIP,
1859 phba->fcf.current_rec.fcf_indx, 1869 "2836 New FCF matches in-use "
1870 "FCF (x%x)\n",
1871 phba->fcf.current_rec.fcf_indx);
1872 goto out;
1873 } else
1874 lpfc_printf_log(phba, KERN_ERR, LOG_FIP,
1875 "2863 New FCF (x%x) matches "
1876 "property of in-use FCF (x%x)\n",
1860 bf_get(lpfc_fcf_record_fcf_index, 1877 bf_get(lpfc_fcf_record_fcf_index,
1861 new_fcf_record)); 1878 new_fcf_record),
1862 goto out; 1879 phba->fcf.current_rec.fcf_indx);
1863 } 1880 }
1864 /* 1881 /*
1865 * Read next FCF record from HBA searching for the matching 1882 * Read next FCF record from HBA searching for the matching
@@ -2069,28 +2086,6 @@ read_next_fcf:
2069 LPFC_FCOE_FCF_GET_FIRST); 2086 LPFC_FCOE_FCF_GET_FIRST);
2070 return; 2087 return;
2071 } 2088 }
2072
2073 /*
2074 * Otherwise, initial scan or post linkdown rescan,
2075 * register with the best FCF record found so far
2076 * through the FCF scanning process.
2077 */
2078
2079 /*
2080 * Mark the initial FCF discovery completed and
2081 * the start of the first round of the roundrobin
2082 * FCF failover.
2083 */
2084 spin_lock_irq(&phba->hbalock);
2085 phba->fcf.fcf_flag &=
2086 ~(FCF_INIT_DISC | FCF_REDISC_RRU);
2087 spin_unlock_irq(&phba->hbalock);
2088 /*
2089 * Set up the initial registered FCF index for FLOGI
2090 * round robin FCF failover
2091 */
2092 phba->fcf.fcf_rr_init_indx =
2093 phba->fcf.current_rec.fcf_indx;
2094 /* Register to the new FCF record */ 2089 /* Register to the new FCF record */
2095 lpfc_register_fcf(phba); 2090 lpfc_register_fcf(phba);
2096 } 2091 }
@@ -3992,6 +3987,16 @@ lpfc_cleanup_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
3992 } 3987 }
3993 3988
3994 spin_lock_irq(&phba->hbalock); 3989 spin_lock_irq(&phba->hbalock);
3990 /* Cleanup REG_LOGIN completions which are not yet processed */
3991 list_for_each_entry(mb, &phba->sli.mboxq_cmpl, list) {
3992 if ((mb->u.mb.mbxCommand != MBX_REG_LOGIN64) ||
3993 (ndlp != (struct lpfc_nodelist *) mb->context2))
3994 continue;
3995
3996 mb->context2 = NULL;
3997 mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
3998 }
3999
3995 list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) { 4000 list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
3996 if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) && 4001 if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
3997 (ndlp == (struct lpfc_nodelist *) mb->context2)) { 4002 (ndlp == (struct lpfc_nodelist *) mb->context2)) {
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index 295c7ddb36c1..9a2e2c792876 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -2234,10 +2234,9 @@ lpfc_stop_vport_timers(struct lpfc_vport *vport)
2234void 2234void
2235__lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba) 2235__lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba)
2236{ 2236{
2237 /* Clear pending FCF rediscovery wait and failover in progress flags */ 2237 /* Clear pending FCF rediscovery wait flag */
2238 phba->fcf.fcf_flag &= ~(FCF_REDISC_PEND | 2238 phba->fcf.fcf_flag &= ~FCF_REDISC_PEND;
2239 FCF_DEAD_DISC | 2239
2240 FCF_ACVL_DISC);
2241 /* Now, try to stop the timer */ 2240 /* Now, try to stop the timer */
2242 del_timer(&phba->fcf.redisc_wait); 2241 del_timer(&phba->fcf.redisc_wait);
2243} 2242}
@@ -2261,6 +2260,8 @@ lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *phba)
2261 return; 2260 return;
2262 } 2261 }
2263 __lpfc_sli4_stop_fcf_redisc_wait_timer(phba); 2262 __lpfc_sli4_stop_fcf_redisc_wait_timer(phba);
2263 /* Clear failover in progress flags */
2264 phba->fcf.fcf_flag &= ~(FCF_DEAD_DISC | FCF_ACVL_DISC);
2264 spin_unlock_irq(&phba->hbalock); 2265 spin_unlock_irq(&phba->hbalock);
2265} 2266}
2266 2267