diff options
author | James Smart <james.smart@emulex.com> | 2010-10-22 11:05:36 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-10-25 17:35:36 -0400 |
commit | 5ac6b303834aa74855ecc3db98b4b1d9cad0de2f (patch) | |
tree | 62a3dc32a25d30dcdc4790151e1a01f51b431e9b | |
parent | 32622bdea031a5a6a6efd6dac9b317de46d5c6f8 (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.c | 20 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 79 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_init.c | 9 |
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) | |||
2234 | void | 2234 | void |
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 | ||