diff options
author | James Smart <james.smart@emulex.com> | 2010-03-15 11:25:44 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-04-11 10:23:51 -0400 |
commit | 4b40c59eced94eea7f4583ffb0dbc33a5fa92499 (patch) | |
tree | 1a60a3f4e931b5a7295b1f2eed2a8d84f5062695 /drivers/scsi/lpfc | |
parent | e2af0d2ed86a2415b0562526601cf2d5cae5a96d (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.h | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_attr.c | 2 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 7 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_hbadisc.c | 7 | ||||
-rw-r--r-- | drivers/scsi/lpfc/lpfc_nportdisc.c | 43 |
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; | |||
1929 | module_param(lpfc_enable_npiv, int, 0); | 1929 | module_param(lpfc_enable_npiv, int, 0); |
1930 | MODULE_PARM_DESC(lpfc_enable_npiv, "Enable NPIV functionality"); | 1930 | MODULE_PARM_DESC(lpfc_enable_npiv, "Enable NPIV functionality"); |
1931 | lpfc_param_show(enable_npiv); | 1931 | lpfc_param_show(enable_npiv); |
1932 | lpfc_param_init(enable_npiv, 0, 0, 1); | 1932 | lpfc_param_init(enable_npiv, 1, 0, 1); |
1933 | static DEVICE_ATTR(lpfc_enable_npiv, S_IRUGO, | 1933 | static 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 | } |
561 | out: | ||
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 | ||