aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc
diff options
context:
space:
mode:
authorJames Smart <james.smart@emulex.com>2010-03-15 11:25:44 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-04-11 10:23:51 -0400
commit4b40c59eced94eea7f4583ffb0dbc33a5fa92499 (patch)
tree1a60a3f4e931b5a7295b1f2eed2a8d84f5062695 /drivers/scsi/lpfc
parente2af0d2ed86a2415b0562526601cf2d5cae5a96d (diff)
[SCSI] lpfc 8.3.11: NPIV changes
- Enable NPIV by default. - Added code to handle unsolicited LOGO on physical port. 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/scsi/lpfc')
-rw-r--r--drivers/scsi/lpfc/lpfc.h2
-rw-r--r--drivers/scsi/lpfc/lpfc_attr.c2
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c7
-rw-r--r--drivers/scsi/lpfc/lpfc_hbadisc.c7
-rw-r--r--drivers/scsi/lpfc/lpfc_nportdisc.c43
5 files changed, 53 insertions, 8 deletions
diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h
index 23b9320539e1..e35a4c71eb9a 100644
--- a/drivers/scsi/lpfc/lpfc.h
+++ b/drivers/scsi/lpfc/lpfc.h
@@ -310,7 +310,9 @@ struct lpfc_vport {
310#define FC_NLP_MORE 0x40 /* More node to process in node tbl */ 310#define FC_NLP_MORE 0x40 /* More node to process in node tbl */
311#define FC_OFFLINE_MODE 0x80 /* Interface is offline for diag */ 311#define FC_OFFLINE_MODE 0x80 /* Interface is offline for diag */
312#define FC_FABRIC 0x100 /* We are fabric attached */ 312#define FC_FABRIC 0x100 /* We are fabric attached */
313#define FC_VPORT_LOGO_RCVD 0x200 /* LOGO received on vport */
313#define FC_RSCN_DISCOVERY 0x400 /* Auth all devices after RSCN */ 314#define FC_RSCN_DISCOVERY 0x400 /* Auth all devices after RSCN */
315#define FC_LOGO_RCVD_DID_CHNG 0x800 /* FDISC on phys port detect DID chng*/
314#define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */ 316#define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */
315#define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */ 317#define FC_ABORT_DISCOVERY 0x8000 /* we want to abort discovery */
316#define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */ 318#define FC_NDISC_ACTIVE 0x10000 /* NPort discovery active */
diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c
index 1849e33e68f9..5df15c65b35b 100644
--- a/drivers/scsi/lpfc/lpfc_attr.c
+++ b/drivers/scsi/lpfc/lpfc_attr.c
@@ -1929,7 +1929,7 @@ int lpfc_enable_npiv = 0;
1929module_param(lpfc_enable_npiv, int, 0); 1929module_param(lpfc_enable_npiv, int, 0);
1930MODULE_PARM_DESC(lpfc_enable_npiv, "Enable NPIV functionality"); 1930MODULE_PARM_DESC(lpfc_enable_npiv, "Enable NPIV functionality");
1931lpfc_param_show(enable_npiv); 1931lpfc_param_show(enable_npiv);
1932lpfc_param_init(enable_npiv, 0, 0, 1); 1932lpfc_param_init(enable_npiv, 1, 0, 1);
1933static DEVICE_ATTR(lpfc_enable_npiv, S_IRUGO, 1933static DEVICE_ATTR(lpfc_enable_npiv, S_IRUGO,
1934 lpfc_enable_npiv_show, NULL); 1934 lpfc_enable_npiv_show, NULL);
1935 1935
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 0a337dab211c..9508661fe825 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -864,6 +864,7 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
864 } 864 }
865 spin_lock_irq(shost->host_lock); 865 spin_lock_irq(shost->host_lock);
866 vport->fc_flag &= ~FC_VPORT_CVL_RCVD; 866 vport->fc_flag &= ~FC_VPORT_CVL_RCVD;
867 vport->fc_flag &= ~FC_VPORT_LOGO_RCVD;
867 spin_unlock_irq(shost->host_lock); 868 spin_unlock_irq(shost->host_lock);
868 869
869 /* 870 /*
@@ -6053,7 +6054,8 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
6053 spin_lock_irq(shost->host_lock); 6054 spin_lock_irq(shost->host_lock);
6054 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; 6055 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
6055 spin_unlock_irq(shost->host_lock); 6056 spin_unlock_irq(shost->host_lock);
6056 if (vport->port_type == LPFC_PHYSICAL_PORT) 6057 if (vport->port_type == LPFC_PHYSICAL_PORT
6058 && !(vport->fc_flag & FC_LOGO_RCVD_DID_CHNG))
6057 lpfc_initial_flogi(vport); 6059 lpfc_initial_flogi(vport);
6058 else 6060 else
6059 lpfc_initial_fdisc(vport); 6061 lpfc_initial_fdisc(vport);
@@ -6289,6 +6291,7 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
6289 } 6291 }
6290 spin_lock_irq(shost->host_lock); 6292 spin_lock_irq(shost->host_lock);
6291 vport->fc_flag &= ~FC_VPORT_CVL_RCVD; 6293 vport->fc_flag &= ~FC_VPORT_CVL_RCVD;
6294 vport->fc_flag &= ~FC_VPORT_LOGO_RCVD;
6292 vport->fc_flag |= FC_FABRIC; 6295 vport->fc_flag |= FC_FABRIC;
6293 if (vport->phba->fc_topology == TOPOLOGY_LOOP) 6296 if (vport->phba->fc_topology == TOPOLOGY_LOOP)
6294 vport->fc_flag |= FC_PUBLIC_LOOP; 6297 vport->fc_flag |= FC_PUBLIC_LOOP;
@@ -6318,6 +6321,8 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
6318 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI; 6321 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
6319 if (phba->sli_rev == LPFC_SLI_REV4) 6322 if (phba->sli_rev == LPFC_SLI_REV4)
6320 vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI; 6323 vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
6324 else
6325 vport->fc_flag |= FC_LOGO_RCVD_DID_CHNG;
6321 spin_unlock_irq(shost->host_lock); 6326 spin_unlock_irq(shost->host_lock);
6322 } 6327 }
6323 6328
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 7c4f389a2f67..d2b55f05aa02 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -3016,7 +3016,12 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
3016 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE); 3016 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
3017 3017
3018 if (vport->port_state == LPFC_FABRIC_CFG_LINK) { 3018 if (vport->port_state == LPFC_FABRIC_CFG_LINK) {
3019 lpfc_start_fdiscs(phba); 3019 /* when physical port receive logo donot start
3020 * vport discovery */
3021 if (!(vport->fc_flag & FC_LOGO_RCVD_DID_CHNG))
3022 lpfc_start_fdiscs(phba);
3023 else
3024 vport->fc_flag &= ~FC_LOGO_RCVD_DID_CHNG ;
3020 lpfc_do_scr_ns_plogi(phba, vport); 3025 lpfc_do_scr_ns_plogi(phba, vport);
3021 } 3026 }
3022 3027
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c
index e331204a4d56..e1086da69061 100644
--- a/drivers/scsi/lpfc/lpfc_nportdisc.c
+++ b/drivers/scsi/lpfc/lpfc_nportdisc.c
@@ -493,6 +493,9 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
493 struct lpfc_iocbq *cmdiocb, uint32_t els_cmd) 493 struct lpfc_iocbq *cmdiocb, uint32_t els_cmd)
494{ 494{
495 struct Scsi_Host *shost = lpfc_shost_from_vport(vport); 495 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
496 struct lpfc_hba *phba = vport->phba;
497 struct lpfc_vport **vports;
498 int i, active_vlink_present = 0 ;
496 499
497 /* Put ndlp in NPR state with 1 sec timeout for plogi, ACC logo */ 500 /* Put ndlp in NPR state with 1 sec timeout for plogi, ACC logo */
498 /* Only call LOGO ACC for first LOGO, this avoids sending unnecessary 501 /* Only call LOGO ACC for first LOGO, this avoids sending unnecessary
@@ -505,15 +508,44 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
505 lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL); 508 lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);
506 else 509 else
507 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); 510 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
508 if ((ndlp->nlp_DID == Fabric_DID) && 511 if (ndlp->nlp_DID == Fabric_DID) {
509 vport->port_type == LPFC_NPIV_PORT) { 512 if (vport->port_state <= LPFC_FDISC)
513 goto out;
510 lpfc_linkdown_port(vport); 514 lpfc_linkdown_port(vport);
511 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ * 1);
512 spin_lock_irq(shost->host_lock); 515 spin_lock_irq(shost->host_lock);
513 ndlp->nlp_flag |= NLP_DELAY_TMO; 516 vport->fc_flag |= FC_VPORT_LOGO_RCVD;
514 spin_unlock_irq(shost->host_lock); 517 spin_unlock_irq(shost->host_lock);
518 vports = lpfc_create_vport_work_array(phba);
519 if (vports) {
520 for (i = 0; i <= phba->max_vports && vports[i] != NULL;
521 i++) {
522 if ((!(vports[i]->fc_flag &
523 FC_VPORT_LOGO_RCVD)) &&
524 (vports[i]->port_state > LPFC_FDISC)) {
525 active_vlink_present = 1;
526 break;
527 }
528 }
529 lpfc_destroy_vport_work_array(phba, vports);
530 }
515 531
516 ndlp->nlp_last_elscmd = ELS_CMD_FDISC; 532 if (active_vlink_present) {
533 /*
534 * If there are other active VLinks present,
535 * re-instantiate the Vlink using FDISC.
536 */
537 mod_timer(&ndlp->nlp_delayfunc, jiffies + HZ);
538 spin_lock_irq(shost->host_lock);
539 ndlp->nlp_flag |= NLP_DELAY_TMO;
540 spin_unlock_irq(shost->host_lock);
541 ndlp->nlp_last_elscmd = ELS_CMD_FDISC;
542 vport->port_state = LPFC_FDISC;
543 } else {
544 spin_lock_irq(shost->host_lock);
545 phba->pport->fc_flag &= ~FC_LOGO_RCVD_DID_CHNG;
546 spin_unlock_irq(shost->host_lock);
547 lpfc_retry_pport_discovery(phba);
548 }
517 } else if ((!(ndlp->nlp_type & NLP_FABRIC) && 549 } else if ((!(ndlp->nlp_type & NLP_FABRIC) &&
518 ((ndlp->nlp_type & NLP_FCP_TARGET) || 550 ((ndlp->nlp_type & NLP_FCP_TARGET) ||
519 !(ndlp->nlp_type & NLP_FCP_INITIATOR))) || 551 !(ndlp->nlp_type & NLP_FCP_INITIATOR))) ||
@@ -526,6 +558,7 @@ lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
526 558
527 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI; 559 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
528 } 560 }
561out:
529 ndlp->nlp_prev_state = ndlp->nlp_state; 562 ndlp->nlp_prev_state = ndlp->nlp_state;
530 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); 563 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
531 564