@@ -3390,11 +3390,21 @@ lpfc_cmpl_els_disc_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
33903390 lpfc_cmpl_els_edc (phba , cmdiocb , rspiocb );
33913391 return ;
33923392 }
3393+
33933394 if (ulp_status ) {
33943395 /* ELS discovery cmd completes with error */
33953396 lpfc_printf_vlog (vport , KERN_WARNING , LOG_ELS | LOG_CGN_MGMT ,
33963397 "4203 ELS cmd x%x error: x%x x%X\n" , cmd ,
33973398 ulp_status , ulp_word4 );
3399+
3400+ /* In the case where the ELS cmd completes with an error and
3401+ * the node does not have RPI registered, the node is
3402+ * outstanding and should put its initial reference.
3403+ */
3404+ if ((cmd == ELS_CMD_SCR || cmd == ELS_CMD_RDF ) &&
3405+ !(ndlp -> fc4_xpt_flags & SCSI_XPT_REGD ) &&
3406+ !test_and_set_bit (NLP_DROPPED , & ndlp -> nlp_flag ))
3407+ lpfc_nlp_put (ndlp );
33983408 goto out ;
33993409 }
34003410
@@ -3463,6 +3473,7 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint8_t retry)
34633473 uint8_t * pcmd ;
34643474 uint16_t cmdsize ;
34653475 struct lpfc_nodelist * ndlp ;
3476+ bool node_created = false;
34663477
34673478 cmdsize = (sizeof (uint32_t ) + sizeof (SCR ));
34683479
@@ -3472,21 +3483,21 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint8_t retry)
34723483 if (!ndlp )
34733484 return 1 ;
34743485 lpfc_enqueue_node (vport , ndlp );
3486+ node_created = true;
34753487 }
34763488
34773489 elsiocb = lpfc_prep_els_iocb (vport , 1 , cmdsize , retry , ndlp ,
34783490 ndlp -> nlp_DID , ELS_CMD_SCR );
34793491 if (!elsiocb )
3480- return 1 ;
3492+ goto out_node_created ;
34813493
34823494 if (phba -> sli_rev == LPFC_SLI_REV4 ) {
34833495 rc = lpfc_reg_fab_ctrl_node (vport , ndlp );
34843496 if (rc ) {
3485- lpfc_els_free_iocb (phba , elsiocb );
34863497 lpfc_printf_vlog (vport , KERN_ERR , LOG_NODE ,
34873498 "0937 %s: Failed to reg fc node, rc %d\n" ,
34883499 __func__ , rc );
3489- return 1 ;
3500+ goto out_free_iocb ;
34903501 }
34913502 }
34923503 pcmd = (uint8_t * )elsiocb -> cmd_dmabuf -> virt ;
@@ -3505,23 +3516,27 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint8_t retry)
35053516 phba -> fc_stat .elsXmitSCR ++ ;
35063517 elsiocb -> cmd_cmpl = lpfc_cmpl_els_disc_cmd ;
35073518 elsiocb -> ndlp = lpfc_nlp_get (ndlp );
3508- if (!elsiocb -> ndlp ) {
3509- lpfc_els_free_iocb (phba , elsiocb );
3510- return 1 ;
3511- }
3519+ if (!elsiocb -> ndlp )
3520+ goto out_free_iocb ;
35123521
35133522 lpfc_debugfs_disc_trc (vport , LPFC_DISC_TRC_ELS_CMD ,
35143523 "Issue SCR: did:x%x refcnt %d" ,
35153524 ndlp -> nlp_DID , kref_read (& ndlp -> kref ), 0 );
35163525
35173526 rc = lpfc_sli_issue_iocb (phba , LPFC_ELS_RING , elsiocb , 0 );
3518- if (rc == IOCB_ERROR ) {
3519- lpfc_els_free_iocb (phba , elsiocb );
3520- lpfc_nlp_put (ndlp );
3521- return 1 ;
3522- }
3527+ if (rc == IOCB_ERROR )
3528+ goto out_iocb_error ;
35233529
35243530 return 0 ;
3531+
3532+ out_iocb_error :
3533+ lpfc_nlp_put (ndlp );
3534+ out_free_iocb :
3535+ lpfc_els_free_iocb (phba , elsiocb );
3536+ out_node_created :
3537+ if (node_created )
3538+ lpfc_nlp_put (ndlp );
3539+ return 1 ;
35253540}
35263541
35273542/**
@@ -3734,7 +3749,12 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
37343749 *
37353750 * Return code
37363751 * 0 - Successfully issued rdf command
3737- * 1 - Failed to issue rdf command
3752+ * < 0 - Failed to issue rdf command
3753+ * -EACCES - RDF not required for NPIV_PORT
3754+ * -ENODEV - No fabric controller device available
3755+ * -ENOMEM - No available memory
3756+ * -EIO - The mailbox failed to complete successfully.
3757+ *
37383758 **/
37393759int
37403760lpfc_issue_els_rdf (struct lpfc_vport * vport , uint8_t retry )
@@ -3745,25 +3765,30 @@ lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry)
37453765 struct lpfc_nodelist * ndlp ;
37463766 uint16_t cmdsize ;
37473767 int rc ;
3768+ bool node_created = false;
3769+ int err ;
37483770
37493771 cmdsize = sizeof (* prdf );
37503772
3773+ /* RDF ELS is not required on an NPIV VN_Port. */
3774+ if (vport -> port_type == LPFC_NPIV_PORT )
3775+ return - EACCES ;
3776+
37513777 ndlp = lpfc_findnode_did (vport , Fabric_Cntl_DID );
37523778 if (!ndlp ) {
37533779 ndlp = lpfc_nlp_init (vport , Fabric_Cntl_DID );
37543780 if (!ndlp )
37553781 return - ENODEV ;
37563782 lpfc_enqueue_node (vport , ndlp );
3783+ node_created = true;
37573784 }
37583785
3759- /* RDF ELS is not required on an NPIV VN_Port. */
3760- if (vport -> port_type == LPFC_NPIV_PORT )
3761- return - EACCES ;
3762-
37633786 elsiocb = lpfc_prep_els_iocb (vport , 1 , cmdsize , retry , ndlp ,
37643787 ndlp -> nlp_DID , ELS_CMD_RDF );
3765- if (!elsiocb )
3766- return - ENOMEM ;
3788+ if (!elsiocb ) {
3789+ err = - ENOMEM ;
3790+ goto out_node_created ;
3791+ }
37673792
37683793 /* Configure the payload for the supported FPIN events. */
37693794 prdf = (struct lpfc_els_rdf_req * )elsiocb -> cmd_dmabuf -> virt ;
@@ -3789,8 +3814,8 @@ lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry)
37893814 elsiocb -> cmd_cmpl = lpfc_cmpl_els_disc_cmd ;
37903815 elsiocb -> ndlp = lpfc_nlp_get (ndlp );
37913816 if (!elsiocb -> ndlp ) {
3792- lpfc_els_free_iocb ( phba , elsiocb ) ;
3793- return - EIO ;
3817+ err = - EIO ;
3818+ goto out_free_iocb ;
37943819 }
37953820
37963821 lpfc_debugfs_disc_trc (vport , LPFC_DISC_TRC_ELS_CMD ,
@@ -3799,11 +3824,19 @@ lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry)
37993824
38003825 rc = lpfc_sli_issue_iocb (phba , LPFC_ELS_RING , elsiocb , 0 );
38013826 if (rc == IOCB_ERROR ) {
3802- lpfc_els_free_iocb (phba , elsiocb );
3803- lpfc_nlp_put (ndlp );
3804- return - EIO ;
3827+ err = - EIO ;
3828+ goto out_iocb_error ;
38053829 }
38063830 return 0 ;
3831+
3832+ out_iocb_error :
3833+ lpfc_nlp_put (ndlp );
3834+ out_free_iocb :
3835+ lpfc_els_free_iocb (phba , elsiocb );
3836+ out_node_created :
3837+ if (node_created )
3838+ lpfc_nlp_put (ndlp );
3839+ return err ;
38073840}
38083841
38093842 /**
@@ -3824,19 +3857,23 @@ static int
38243857lpfc_els_rcv_rdf (struct lpfc_vport * vport , struct lpfc_iocbq * cmdiocb ,
38253858 struct lpfc_nodelist * ndlp )
38263859{
3860+ int rc ;
3861+
3862+ rc = lpfc_els_rsp_acc (vport , ELS_CMD_RDF , cmdiocb , ndlp , NULL );
38273863 /* Send LS_ACC */
3828- if (lpfc_els_rsp_acc ( vport , ELS_CMD_RDF , cmdiocb , ndlp , NULL ) ) {
3864+ if (rc ) {
38293865 lpfc_printf_vlog (vport , KERN_INFO , LOG_ELS | LOG_CGN_MGMT ,
3830- "1623 Failed to RDF_ACC from x%x for x%x\n" ,
3831- ndlp -> nlp_DID , vport -> fc_myDID );
3866+ "1623 Failed to RDF_ACC from x%x for x%x Data: %d \n" ,
3867+ ndlp -> nlp_DID , vport -> fc_myDID , rc );
38323868 return - EIO ;
38333869 }
38343870
3871+ rc = lpfc_issue_els_rdf (vport , 0 );
38353872 /* Issue new RDF for reregistering */
3836- if (lpfc_issue_els_rdf ( vport , 0 ) ) {
3873+ if (rc ) {
38373874 lpfc_printf_vlog (vport , KERN_INFO , LOG_ELS | LOG_CGN_MGMT ,
3838- "2623 Failed to re register RDF for x%x\n" ,
3839- vport -> fc_myDID );
3875+ "2623 Failed to re register RDF for x%x Data: %d \n" ,
3876+ vport -> fc_myDID , rc );
38403877 return - EIO ;
38413878 }
38423879
0 commit comments