aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_init.c
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2010-01-26 23:08:03 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-02-08 19:38:28 -0500
commit695a814e18561c52456acf5051fac0ea4b8111da (patch)
tree3cbe747f38bbd5dae092e643de42be1a735d9552 /drivers/scsi/lpfc/lpfc_init.c
parent341af10239c4c87192bf762f53c7bcb1f3a1e767 (diff)
[SCSI] lpfc 8.3.8: BugFixes: Discovery relates changes
Discovery relates changes: - Separated VPI_REGISTERED state of physical port into VFI_REGISTERED and VPI_REGISTERED state so that driver can unregister physical port VPI independent of VFI. - Add code to unregister, re-init and re-register physical port VPI when physical port NportID change. - Add code to unregister and re-register VPI of a vport when its Nport ID change. - Add code in FDISC completion path to re-start FLOGI discovery when a FDISC complete with LOGIN_REQUIRED reason code. - Fix a memory leak in lpfc_init_vpi_cmpl - Add code to start a timer for vport to retry FDISC when CVL is received by a vport or physical port. If all Nports receive CVLs, then all timers are cancelled and a logical link level discovery will be started after one second. - Flush ELS commands after killing all delayed ELS commands. Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_init.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_init.c44
1 files changed, 41 insertions, 3 deletions
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c
index b8eb1b6e5e77..4d20c4148fae 100644
--- a/drivers/scsi/lpfc/lpfc_init.c
+++ b/drivers/scsi/lpfc/lpfc_init.c
@@ -2246,6 +2246,9 @@ lpfc_offline_prep(struct lpfc_hba * phba)
2246 if (vports[i]->load_flag & FC_UNLOADING) 2246 if (vports[i]->load_flag & FC_UNLOADING)
2247 continue; 2247 continue;
2248 vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED; 2248 vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED;
2249 vports[i]->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
2250 vports[i]->fc_flag &= ~FC_VFI_REGISTERED;
2251
2249 shost = lpfc_shost_from_vport(vports[i]); 2252 shost = lpfc_shost_from_vport(vports[i]);
2250 list_for_each_entry_safe(ndlp, next_ndlp, 2253 list_for_each_entry_safe(ndlp, next_ndlp,
2251 &vports[i]->fc_nodes, 2254 &vports[i]->fc_nodes,
@@ -3007,6 +3010,9 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
3007 struct lpfc_nodelist *ndlp; 3010 struct lpfc_nodelist *ndlp;
3008 struct Scsi_Host *shost; 3011 struct Scsi_Host *shost;
3009 uint32_t link_state; 3012 uint32_t link_state;
3013 int active_vlink_present;
3014 struct lpfc_vport **vports;
3015 int i;
3010 3016
3011 phba->fc_eventTag = acqe_fcoe->event_tag; 3017 phba->fc_eventTag = acqe_fcoe->event_tag;
3012 phba->fcoe_eventtag = acqe_fcoe->event_tag; 3018 phba->fcoe_eventtag = acqe_fcoe->event_tag;
@@ -3074,14 +3080,46 @@ lpfc_sli4_async_fcoe_evt(struct lpfc_hba *phba,
3074 if (!ndlp) 3080 if (!ndlp)
3075 break; 3081 break;
3076 shost = lpfc_shost_from_vport(vport); 3082 shost = lpfc_shost_from_vport(vport);
3083 if (phba->pport->port_state <= LPFC_FLOGI)
3084 break;
3085 /* If virtual link is not yet instantiated ignore CVL */
3086 if (vport->port_state <= LPFC_FDISC)
3087 break;
3088
3077 lpfc_linkdown_port(vport); 3089 lpfc_linkdown_port(vport);
3078 if (vport->port_type != LPFC_NPIV_PORT) { 3090 lpfc_cleanup_pending_mbox(vport);
3091 spin_lock_irq(shost->host_lock);
3092 vport->fc_flag |= FC_VPORT_CVL_RCVD;
3093 spin_unlock_irq(shost->host_lock);
3094 active_vlink_present = 0;
3095
3096 vports = lpfc_create_vport_work_array(phba);
3097 if (vports) {
3098 for (i = 0; i <= phba->max_vports && vports[i] != NULL;
3099 i++) {
3100 if ((!(vports[i]->fc_flag &
3101 FC_VPORT_CVL_RCVD)) &&
3102 (vports[i]->port_state > LPFC_FDISC)) {
3103 active_vlink_present = 1;
3104 break;
3105 }
3106 }
3107 lpfc_destroy_vport_work_array(phba, vports);
3108 }
3109
3110 if (active_vlink_present) {
3111 /*
3112 * If there are other active VLinks present,
3113 * re-instantiate the Vlink using FDISC.
3114 */
3079 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ); 3115 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
3080 spin_lock_irq(shost->host_lock); 3116 spin_lock_irq(shost->host_lock);
3081 ndlp->nlp_flag |= NLP_DELAY_TMO; 3117 ndlp->nlp_flag |= NLP_DELAY_TMO;
3082 spin_unlock_irq(shost->host_lock); 3118 spin_unlock_irq(shost->host_lock);
3083 ndlp->nlp_last_elscmd = ELS_CMD_FLOGI; 3119 ndlp->nlp_last_elscmd = ELS_CMD_FDISC;
3084 vport->port_state = LPFC_FLOGI; 3120 vport->port_state = LPFC_FDISC;
3121 } else {
3122 lpfc_retry_pport_discovery(phba);
3085 } 3123 }
3086 break; 3124 break;
3087 default: 3125 default: