aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/lpfc/lpfc_els.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r--drivers/scsi/lpfc/lpfc_els.c125
1 files changed, 98 insertions, 27 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c
index 0b662db23284..7afc757338de 100644
--- a/drivers/scsi/lpfc/lpfc_els.c
+++ b/drivers/scsi/lpfc/lpfc_els.c
@@ -421,13 +421,13 @@ fail:
421 * @vport: pointer to a host virtual N_Port data structure. 421 * @vport: pointer to a host virtual N_Port data structure.
422 * 422 *
423 * This routine issues a REG_VFI mailbox for the vfi, vpi, fcfi triplet for 423 * This routine issues a REG_VFI mailbox for the vfi, vpi, fcfi triplet for
424 * the @vport. This mailbox command is necessary for FCoE only. 424 * the @vport. This mailbox command is necessary for SLI4 port only.
425 * 425 *
426 * Return code 426 * Return code
427 * 0 - successfully issued REG_VFI for @vport 427 * 0 - successfully issued REG_VFI for @vport
428 * A failure code otherwise. 428 * A failure code otherwise.
429 **/ 429 **/
430static int 430int
431lpfc_issue_reg_vfi(struct lpfc_vport *vport) 431lpfc_issue_reg_vfi(struct lpfc_vport *vport)
432{ 432{
433 struct lpfc_hba *phba = vport->phba; 433 struct lpfc_hba *phba = vport->phba;
@@ -438,10 +438,14 @@ lpfc_issue_reg_vfi(struct lpfc_vport *vport)
438 int rc = 0; 438 int rc = 0;
439 439
440 sp = &phba->fc_fabparam; 440 sp = &phba->fc_fabparam;
441 ndlp = lpfc_findnode_did(vport, Fabric_DID); 441 /* move forward in case of SLI4 FC port loopback test */
442 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { 442 if ((phba->sli_rev == LPFC_SLI_REV4) &&
443 rc = -ENODEV; 443 !(phba->link_flag & LS_LOOPBACK_MODE)) {
444 goto fail; 444 ndlp = lpfc_findnode_did(vport, Fabric_DID);
445 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
446 rc = -ENODEV;
447 goto fail;
448 }
445 } 449 }
446 450
447 dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); 451 dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
@@ -487,6 +491,54 @@ fail:
487} 491}
488 492
489/** 493/**
494 * lpfc_issue_unreg_vfi - Unregister VFI for this vport's fabric login
495 * @vport: pointer to a host virtual N_Port data structure.
496 *
497 * This routine issues a UNREG_VFI mailbox with the vfi, vpi, fcfi triplet for
498 * the @vport. This mailbox command is necessary for SLI4 port only.
499 *
500 * Return code
501 * 0 - successfully issued REG_VFI for @vport
502 * A failure code otherwise.
503 **/
504int
505lpfc_issue_unreg_vfi(struct lpfc_vport *vport)
506{
507 struct lpfc_hba *phba = vport->phba;
508 struct Scsi_Host *shost;
509 LPFC_MBOXQ_t *mboxq;
510 int rc;
511
512 mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
513 if (!mboxq) {
514 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
515 "2556 UNREG_VFI mbox allocation failed"
516 "HBA state x%x\n", phba->pport->port_state);
517 return -ENOMEM;
518 }
519
520 lpfc_unreg_vfi(mboxq, vport);
521 mboxq->vport = vport;
522 mboxq->mbox_cmpl = lpfc_unregister_vfi_cmpl;
523
524 rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
525 if (rc == MBX_NOT_FINISHED) {
526 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
527 "2557 UNREG_VFI issue mbox failed rc x%x "
528 "HBA state x%x\n",
529 rc, phba->pport->port_state);
530 mempool_free(mboxq, phba->mbox_mem_pool);
531 return -EIO;
532 }
533
534 shost = lpfc_shost_from_vport(vport);
535 spin_lock_irq(shost->host_lock);
536 vport->fc_flag &= ~FC_VFI_REGISTERED;
537 spin_unlock_irq(shost->host_lock);
538 return 0;
539}
540
541/**
490 * lpfc_check_clean_addr_bit - Check whether assigned FCID is clean. 542 * lpfc_check_clean_addr_bit - Check whether assigned FCID is clean.
491 * @vport: pointer to a host virtual N_Port data structure. 543 * @vport: pointer to a host virtual N_Port data structure.
492 * @sp: pointer to service parameter data structure. 544 * @sp: pointer to service parameter data structure.
@@ -615,7 +667,9 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
615 "1816 FLOGI NPIV supported, " 667 "1816 FLOGI NPIV supported, "
616 "response data 0x%x\n", 668 "response data 0x%x\n",
617 sp->cmn.response_multiple_NPort); 669 sp->cmn.response_multiple_NPort);
670 spin_lock_irq(&phba->hbalock);
618 phba->link_flag |= LS_NPIV_FAB_SUPPORTED; 671 phba->link_flag |= LS_NPIV_FAB_SUPPORTED;
672 spin_unlock_irq(&phba->hbalock);
619 } else { 673 } else {
620 /* Because we asked f/w for NPIV it still expects us 674 /* Because we asked f/w for NPIV it still expects us
621 to call reg_vnpid atleast for the physcial host */ 675 to call reg_vnpid atleast for the physcial host */
@@ -623,7 +677,9 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
623 LOG_ELS | LOG_VPORT, 677 LOG_ELS | LOG_VPORT,
624 "1817 Fabric does not support NPIV " 678 "1817 Fabric does not support NPIV "
625 "- configuring single port mode.\n"); 679 "- configuring single port mode.\n");
680 spin_lock_irq(&phba->hbalock);
626 phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED; 681 phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED;
682 spin_unlock_irq(&phba->hbalock);
627 } 683 }
628 } 684 }
629 685
@@ -686,11 +742,16 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
686 lpfc_do_scr_ns_plogi(phba, vport); 742 lpfc_do_scr_ns_plogi(phba, vport);
687 } else if (vport->fc_flag & FC_VFI_REGISTERED) 743 } else if (vport->fc_flag & FC_VFI_REGISTERED)
688 lpfc_issue_init_vpi(vport); 744 lpfc_issue_init_vpi(vport);
689 else 745 else {
746 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
747 "3135 Need register VFI: (x%x/%x)\n",
748 vport->fc_prevDID, vport->fc_myDID);
690 lpfc_issue_reg_vfi(vport); 749 lpfc_issue_reg_vfi(vport);
750 }
691 } 751 }
692 return 0; 752 return 0;
693} 753}
754
694/** 755/**
695 * lpfc_cmpl_els_flogi_nport - Completion function for flogi to an N_Port 756 * lpfc_cmpl_els_flogi_nport - Completion function for flogi to an N_Port
696 * @vport: pointer to a host virtual N_Port data structure. 757 * @vport: pointer to a host virtual N_Port data structure.
@@ -907,9 +968,8 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
907 * LPFC_MAX_DISC_THREADS (32). Scanning in the case of no 968 * LPFC_MAX_DISC_THREADS (32). Scanning in the case of no
908 * alpa map would take too long otherwise. 969 * alpa map would take too long otherwise.
909 */ 970 */
910 if (phba->alpa_map[0] == 0) { 971 if (phba->alpa_map[0] == 0)
911 vport->cfg_discovery_threads = LPFC_MAX_DISC_THREADS; 972 vport->cfg_discovery_threads = LPFC_MAX_DISC_THREADS;
912 }
913 if ((phba->sli_rev == LPFC_SLI_REV4) && 973 if ((phba->sli_rev == LPFC_SLI_REV4) &&
914 (!(vport->fc_flag & FC_VFI_REGISTERED) || 974 (!(vport->fc_flag & FC_VFI_REGISTERED) ||
915 (vport->fc_prevDID != vport->fc_myDID))) { 975 (vport->fc_prevDID != vport->fc_myDID))) {
@@ -1164,8 +1224,7 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba)
1164 spin_lock_irq(&phba->hbalock); 1224 spin_lock_irq(&phba->hbalock);
1165 list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) { 1225 list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {
1166 icmd = &iocb->iocb; 1226 icmd = &iocb->iocb;
1167 if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR && 1227 if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR) {
1168 icmd->un.elsreq64.bdl.ulpIoTag32) {
1169 ndlp = (struct lpfc_nodelist *)(iocb->context1); 1228 ndlp = (struct lpfc_nodelist *)(iocb->context1);
1170 if (ndlp && NLP_CHK_NODE_ACT(ndlp) && 1229 if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
1171 (ndlp->nlp_DID == Fabric_DID)) 1230 (ndlp->nlp_DID == Fabric_DID))
@@ -4879,23 +4938,31 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4879 sizeof(struct lpfc_name)); 4938 sizeof(struct lpfc_name));
4880 4939
4881 if (!rc) { 4940 if (!rc) {
4882 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); 4941 if (phba->sli_rev < LPFC_SLI_REV4) {
4883 if (!mbox) 4942 mbox = mempool_alloc(phba->mbox_mem_pool,
4943 GFP_KERNEL);
4944 if (!mbox)
4945 return 1;
4946 lpfc_linkdown(phba);
4947 lpfc_init_link(phba, mbox,
4948 phba->cfg_topology,
4949 phba->cfg_link_speed);
4950 mbox->u.mb.un.varInitLnk.lipsr_AL_PA = 0;
4951 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
4952 mbox->vport = vport;
4953 rc = lpfc_sli_issue_mbox(phba, mbox,
4954 MBX_NOWAIT);
4955 lpfc_set_loopback_flag(phba);
4956 if (rc == MBX_NOT_FINISHED)
4957 mempool_free(mbox, phba->mbox_mem_pool);
4884 return 1; 4958 return 1;
4885 4959 } else {
4886 lpfc_linkdown(phba); 4960 /* abort the flogi coming back to ourselves
4887 lpfc_init_link(phba, mbox, 4961 * due to external loopback on the port.
4888 phba->cfg_topology, 4962 */
4889 phba->cfg_link_speed); 4963 lpfc_els_abort_flogi(phba);
4890 mbox->u.mb.un.varInitLnk.lipsr_AL_PA = 0; 4964 return 0;
4891 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
4892 mbox->vport = vport;
4893 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
4894 lpfc_set_loopback_flag(phba);
4895 if (rc == MBX_NOT_FINISHED) {
4896 mempool_free(mbox, phba->mbox_mem_pool);
4897 } 4965 }
4898 return 1;
4899 } else if (rc > 0) { /* greater than */ 4966 } else if (rc > 0) { /* greater than */
4900 spin_lock_irq(shost->host_lock); 4967 spin_lock_irq(shost->host_lock);
4901 vport->fc_flag |= FC_PT2PT_PLOGI; 4968 vport->fc_flag |= FC_PT2PT_PLOGI;
@@ -5850,8 +5917,12 @@ lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
5850 vport->fc_myDID = vport->fc_prevDID; 5917 vport->fc_myDID = vport->fc_prevDID;
5851 if (phba->sli_rev < LPFC_SLI_REV4) 5918 if (phba->sli_rev < LPFC_SLI_REV4)
5852 lpfc_issue_fabric_reglogin(vport); 5919 lpfc_issue_fabric_reglogin(vport);
5853 else 5920 else {
5921 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
5922 "3138 Need register VFI: (x%x/%x)\n",
5923 vport->fc_prevDID, vport->fc_myDID);
5854 lpfc_issue_reg_vfi(vport); 5924 lpfc_issue_reg_vfi(vport);
5925 }
5855 } 5926 }
5856 } 5927 }
5857 return 0; 5928 return 0;