diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 410 |
1 files changed, 318 insertions, 92 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index f60c85d791c7..33fbc1666946 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "lpfc_logmsg.h" | 36 | #include "lpfc_logmsg.h" |
37 | #include "lpfc_crtn.h" | 37 | #include "lpfc_crtn.h" |
38 | #include "lpfc_vport.h" | 38 | #include "lpfc_vport.h" |
39 | #include "lpfc_debugfs.h" | ||
39 | 40 | ||
40 | static int lpfc_els_retry(struct lpfc_hba *, struct lpfc_iocbq *, | 41 | static int lpfc_els_retry(struct lpfc_hba *, struct lpfc_iocbq *, |
41 | struct lpfc_iocbq *); | 42 | struct lpfc_iocbq *); |
@@ -44,7 +45,7 @@ static void lpfc_cmpl_fabric_iocb(struct lpfc_hba *, struct lpfc_iocbq *, | |||
44 | 45 | ||
45 | static int lpfc_max_els_tries = 3; | 46 | static int lpfc_max_els_tries = 3; |
46 | 47 | ||
47 | static int | 48 | int |
48 | lpfc_els_chk_latt(struct lpfc_vport *vport) | 49 | lpfc_els_chk_latt(struct lpfc_vport *vport) |
49 | { | 50 | { |
50 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 51 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
@@ -353,7 +354,6 @@ lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
353 | "%d:1817 Fabric does not support NPIV " | 354 | "%d:1817 Fabric does not support NPIV " |
354 | "- configuring single port mode.\n", | 355 | "- configuring single port mode.\n", |
355 | phba->brd_no); | 356 | phba->brd_no); |
356 | phba->vpi_cnt = 1; | ||
357 | phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED; | 357 | phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED; |
358 | } | 358 | } |
359 | } | 359 | } |
@@ -406,7 +406,6 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
406 | 406 | ||
407 | spin_lock_irq(shost->host_lock); | 407 | spin_lock_irq(shost->host_lock); |
408 | vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); | 408 | vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); |
409 | phba->vpi_cnt = 1; | ||
410 | spin_unlock_irq(shost->host_lock); | 409 | spin_unlock_irq(shost->host_lock); |
411 | 410 | ||
412 | phba->fc_edtov = FF_DEF_EDTOV; | 411 | phba->fc_edtov = FF_DEF_EDTOV; |
@@ -499,6 +498,11 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
499 | goto out; | 498 | goto out; |
500 | } | 499 | } |
501 | 500 | ||
501 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, | ||
502 | "FLOGI cmpl: status:x%x/x%x state:x%x", | ||
503 | irsp->ulpStatus, irsp->un.ulpWord[4], | ||
504 | vport->port_state); | ||
505 | |||
502 | if (irsp->ulpStatus) { | 506 | if (irsp->ulpStatus) { |
503 | /* Check for retry */ | 507 | /* Check for retry */ |
504 | if (lpfc_els_retry(phba, cmdiocb, rspiocb)) | 508 | if (lpfc_els_retry(phba, cmdiocb, rspiocb)) |
@@ -507,7 +511,6 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
507 | /* FLOGI failed, so there is no fabric */ | 511 | /* FLOGI failed, so there is no fabric */ |
508 | spin_lock_irq(shost->host_lock); | 512 | spin_lock_irq(shost->host_lock); |
509 | vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); | 513 | vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP); |
510 | phba->vpi_cnt = 1; | ||
511 | spin_unlock_irq(shost->host_lock); | 514 | spin_unlock_irq(shost->host_lock); |
512 | 515 | ||
513 | /* If private loop, then allow max outstanding els to be | 516 | /* If private loop, then allow max outstanding els to be |
@@ -560,11 +563,8 @@ lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
560 | 563 | ||
561 | flogifail: | 564 | flogifail: |
562 | lpfc_nlp_put(ndlp); | 565 | lpfc_nlp_put(ndlp); |
563 | phba->vpi_cnt = 1; | ||
564 | 566 | ||
565 | if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT || | 567 | if (!lpfc_error_lost_link(irsp)) { |
566 | (irsp->un.ulpWord[4] != IOERR_SLI_ABORTED && | ||
567 | irsp->un.ulpWord[4] != IOERR_SLI_DOWN)) { | ||
568 | /* FLOGI failed, so just use loop map to make discovery list */ | 568 | /* FLOGI failed, so just use loop map to make discovery list */ |
569 | lpfc_disc_list_loopmap(vport); | 569 | lpfc_disc_list_loopmap(vport); |
570 | 570 | ||
@@ -627,6 +627,11 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
627 | icmd->ulpCt_l = 0; | 627 | icmd->ulpCt_l = 0; |
628 | } | 628 | } |
629 | 629 | ||
630 | if (phba->fc_topology != TOPOLOGY_LOOP) { | ||
631 | icmd->un.elsreq64.myID = 0; | ||
632 | icmd->un.elsreq64.fl = 1; | ||
633 | } | ||
634 | |||
630 | tmo = phba->fc_ratov; | 635 | tmo = phba->fc_ratov; |
631 | phba->fc_ratov = LPFC_DISC_FLOGI_TMO; | 636 | phba->fc_ratov = LPFC_DISC_FLOGI_TMO; |
632 | lpfc_set_disctmo(vport); | 637 | lpfc_set_disctmo(vport); |
@@ -634,6 +639,11 @@ lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
634 | 639 | ||
635 | phba->fc_stat.elsXmitFLOGI++; | 640 | phba->fc_stat.elsXmitFLOGI++; |
636 | elsiocb->iocb_cmpl = lpfc_cmpl_els_flogi; | 641 | elsiocb->iocb_cmpl = lpfc_cmpl_els_flogi; |
642 | |||
643 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, | ||
644 | "Issue FLOGI: opt:x%x", | ||
645 | phba->sli3_options, 0, 0); | ||
646 | |||
637 | rc = lpfc_issue_fabric_iocb(phba, elsiocb); | 647 | rc = lpfc_issue_fabric_iocb(phba, elsiocb); |
638 | if (rc == IOCB_ERROR) { | 648 | if (rc == IOCB_ERROR) { |
639 | lpfc_els_free_iocb(phba, elsiocb); | 649 | lpfc_els_free_iocb(phba, elsiocb); |
@@ -816,6 +826,11 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
816 | cmdiocb->context_un.rsp_iocb = rspiocb; | 826 | cmdiocb->context_un.rsp_iocb = rspiocb; |
817 | 827 | ||
818 | irsp = &rspiocb->iocb; | 828 | irsp = &rspiocb->iocb; |
829 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, | ||
830 | "PLOGI cmpl: status:x%x/x%x did:x%x", | ||
831 | irsp->ulpStatus, irsp->un.ulpWord[4], | ||
832 | irsp->un.elsreq64.remoteID); | ||
833 | |||
819 | ndlp = lpfc_findnode_did(vport, irsp->un.elsreq64.remoteID); | 834 | ndlp = lpfc_findnode_did(vport, irsp->un.elsreq64.remoteID); |
820 | if (!ndlp) { | 835 | if (!ndlp) { |
821 | lpfc_printf_log(phba, KERN_ERR, LOG_ELS, | 836 | lpfc_printf_log(phba, KERN_ERR, LOG_ELS, |
@@ -878,10 +893,7 @@ lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
878 | } | 893 | } |
879 | 894 | ||
880 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ | 895 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ |
881 | if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && | 896 | if (lpfc_error_lost_link(irsp)) { |
882 | ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) || | ||
883 | (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || | ||
884 | (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) { | ||
885 | rc = NLP_STE_FREED_NODE; | 897 | rc = NLP_STE_FREED_NODE; |
886 | } else { | 898 | } else { |
887 | rc = lpfc_disc_state_machine(vport, ndlp, cmdiocb, | 899 | rc = lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
@@ -966,6 +978,10 @@ lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry) | |||
966 | if (sp->cmn.fcphHigh < FC_PH3) | 978 | if (sp->cmn.fcphHigh < FC_PH3) |
967 | sp->cmn.fcphHigh = FC_PH3; | 979 | sp->cmn.fcphHigh = FC_PH3; |
968 | 980 | ||
981 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, | ||
982 | "Issue PLOGI: did:x%x", | ||
983 | did, 0, 0); | ||
984 | |||
969 | phba->fc_stat.elsXmitPLOGI++; | 985 | phba->fc_stat.elsXmitPLOGI++; |
970 | elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi; | 986 | elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi; |
971 | ret = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); | 987 | ret = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); |
@@ -997,6 +1013,11 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
997 | ndlp->nlp_flag &= ~NLP_PRLI_SND; | 1013 | ndlp->nlp_flag &= ~NLP_PRLI_SND; |
998 | spin_unlock_irq(shost->host_lock); | 1014 | spin_unlock_irq(shost->host_lock); |
999 | 1015 | ||
1016 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, | ||
1017 | "PRLI cmpl: status:x%x/x%x did:x%x", | ||
1018 | irsp->ulpStatus, irsp->un.ulpWord[4], | ||
1019 | ndlp->nlp_DID); | ||
1020 | |||
1000 | /* PRLI completes to NPort <nlp_DID> */ | 1021 | /* PRLI completes to NPort <nlp_DID> */ |
1001 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 1022 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
1002 | "%d (%d):0103 PRLI completes to NPort x%x " | 1023 | "%d (%d):0103 PRLI completes to NPort x%x " |
@@ -1018,10 +1039,7 @@ lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1018 | } | 1039 | } |
1019 | /* PRLI failed */ | 1040 | /* PRLI failed */ |
1020 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ | 1041 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ |
1021 | if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && | 1042 | if (lpfc_error_lost_link(irsp)) { |
1022 | ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) || | ||
1023 | (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || | ||
1024 | (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) { | ||
1025 | goto out; | 1043 | goto out; |
1026 | } else { | 1044 | } else { |
1027 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, | 1045 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
@@ -1087,6 +1105,10 @@ lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
1087 | npr->prliType = PRLI_FCP_TYPE; | 1105 | npr->prliType = PRLI_FCP_TYPE; |
1088 | npr->initiatorFunc = 1; | 1106 | npr->initiatorFunc = 1; |
1089 | 1107 | ||
1108 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, | ||
1109 | "Issue PRLI: did:x%x", | ||
1110 | ndlp->nlp_DID, 0, 0); | ||
1111 | |||
1090 | phba->fc_stat.elsXmitPRLI++; | 1112 | phba->fc_stat.elsXmitPRLI++; |
1091 | elsiocb->iocb_cmpl = lpfc_cmpl_els_prli; | 1113 | elsiocb->iocb_cmpl = lpfc_cmpl_els_prli; |
1092 | spin_lock_irq(shost->host_lock); | 1114 | spin_lock_irq(shost->host_lock); |
@@ -1133,6 +1155,8 @@ lpfc_rscn_disc(struct lpfc_vport *vport) | |||
1133 | { | 1155 | { |
1134 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); | 1156 | struct Scsi_Host *shost = lpfc_shost_from_vport(vport); |
1135 | 1157 | ||
1158 | lpfc_can_disctmo(vport); | ||
1159 | |||
1136 | /* RSCN discovery */ | 1160 | /* RSCN discovery */ |
1137 | /* go thru NPR nodes and issue ELS PLOGIs */ | 1161 | /* go thru NPR nodes and issue ELS PLOGIs */ |
1138 | if (vport->fc_npr_cnt) | 1162 | if (vport->fc_npr_cnt) |
@@ -1170,6 +1194,11 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1170 | irsp = &(rspiocb->iocb); | 1194 | irsp = &(rspiocb->iocb); |
1171 | ndlp = (struct lpfc_nodelist *) cmdiocb->context1; | 1195 | ndlp = (struct lpfc_nodelist *) cmdiocb->context1; |
1172 | 1196 | ||
1197 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, | ||
1198 | "ADISC cmpl: status:x%x/x%x did:x%x", | ||
1199 | irsp->ulpStatus, irsp->un.ulpWord[4], | ||
1200 | ndlp->nlp_DID); | ||
1201 | |||
1173 | /* Since ndlp can be freed in the disc state machine, note if this node | 1202 | /* Since ndlp can be freed in the disc state machine, note if this node |
1174 | * is being used during discovery. | 1203 | * is being used during discovery. |
1175 | */ | 1204 | */ |
@@ -1208,12 +1237,9 @@ lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1208 | } | 1237 | } |
1209 | /* ADISC failed */ | 1238 | /* ADISC failed */ |
1210 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ | 1239 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ |
1211 | if ((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) || | 1240 | if (!lpfc_error_lost_link(irsp)) { |
1212 | ((irsp->un.ulpWord[4] != IOERR_SLI_ABORTED) && | ||
1213 | (irsp->un.ulpWord[4] != IOERR_LINK_DOWN) && | ||
1214 | (irsp->un.ulpWord[4] != IOERR_SLI_DOWN))) { | ||
1215 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, | 1241 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
1216 | NLP_EVT_CMPL_ADISC); | 1242 | NLP_EVT_CMPL_ADISC); |
1217 | } | 1243 | } |
1218 | } else { | 1244 | } else { |
1219 | /* Good status, call state machine */ | 1245 | /* Good status, call state machine */ |
@@ -1306,6 +1332,10 @@ lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
1306 | memcpy(&ap->nodeName, &vport->fc_nodename, sizeof(struct lpfc_name)); | 1332 | memcpy(&ap->nodeName, &vport->fc_nodename, sizeof(struct lpfc_name)); |
1307 | ap->DID = be32_to_cpu(vport->fc_myDID); | 1333 | ap->DID = be32_to_cpu(vport->fc_myDID); |
1308 | 1334 | ||
1335 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, | ||
1336 | "Issue ADISC: did:x%x", | ||
1337 | ndlp->nlp_DID, 0, 0); | ||
1338 | |||
1309 | phba->fc_stat.elsXmitADISC++; | 1339 | phba->fc_stat.elsXmitADISC++; |
1310 | elsiocb->iocb_cmpl = lpfc_cmpl_els_adisc; | 1340 | elsiocb->iocb_cmpl = lpfc_cmpl_els_adisc; |
1311 | spin_lock_irq(shost->host_lock); | 1341 | spin_lock_irq(shost->host_lock); |
@@ -1340,6 +1370,11 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1340 | ndlp->nlp_flag &= ~NLP_LOGO_SND; | 1370 | ndlp->nlp_flag &= ~NLP_LOGO_SND; |
1341 | spin_unlock_irq(shost->host_lock); | 1371 | spin_unlock_irq(shost->host_lock); |
1342 | 1372 | ||
1373 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, | ||
1374 | "LOGO cmpl: status:x%x/x%x did:x%x", | ||
1375 | irsp->ulpStatus, irsp->un.ulpWord[4], | ||
1376 | ndlp->nlp_DID); | ||
1377 | |||
1343 | /* LOGO completes to NPort <nlp_DID> */ | 1378 | /* LOGO completes to NPort <nlp_DID> */ |
1344 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 1379 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
1345 | "%d (%d):0105 LOGO completes to NPort x%x " | 1380 | "%d (%d):0105 LOGO completes to NPort x%x " |
@@ -1368,15 +1403,11 @@ lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1368 | goto out; | 1403 | goto out; |
1369 | /* LOGO failed */ | 1404 | /* LOGO failed */ |
1370 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ | 1405 | /* Do not call DSM for lpfc_els_abort'ed ELS cmds */ |
1371 | if ((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && | 1406 | if (lpfc_error_lost_link(irsp)) |
1372 | ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) || | ||
1373 | (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || | ||
1374 | (irsp->un.ulpWord[4] == IOERR_SLI_DOWN))) { | ||
1375 | goto out; | 1407 | goto out; |
1376 | } else { | 1408 | else |
1377 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, | 1409 | lpfc_disc_state_machine(vport, ndlp, cmdiocb, |
1378 | NLP_EVT_CMPL_LOGO); | 1410 | NLP_EVT_CMPL_LOGO); |
1379 | } | ||
1380 | } else { | 1411 | } else { |
1381 | /* Good status, call state machine. | 1412 | /* Good status, call state machine. |
1382 | * This will unregister the rpi if needed. | 1413 | * This will unregister the rpi if needed. |
@@ -1423,6 +1454,10 @@ lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
1423 | pcmd += sizeof(uint32_t); | 1454 | pcmd += sizeof(uint32_t); |
1424 | memcpy(pcmd, &vport->fc_portname, sizeof(struct lpfc_name)); | 1455 | memcpy(pcmd, &vport->fc_portname, sizeof(struct lpfc_name)); |
1425 | 1456 | ||
1457 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, | ||
1458 | "Issue LOGO: did:x%x", | ||
1459 | ndlp->nlp_DID, 0, 0); | ||
1460 | |||
1426 | phba->fc_stat.elsXmitLOGO++; | 1461 | phba->fc_stat.elsXmitLOGO++; |
1427 | elsiocb->iocb_cmpl = lpfc_cmpl_els_logo; | 1462 | elsiocb->iocb_cmpl = lpfc_cmpl_els_logo; |
1428 | spin_lock_irq(shost->host_lock); | 1463 | spin_lock_irq(shost->host_lock); |
@@ -1449,6 +1484,11 @@ lpfc_cmpl_els_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1449 | 1484 | ||
1450 | irsp = &rspiocb->iocb; | 1485 | irsp = &rspiocb->iocb; |
1451 | 1486 | ||
1487 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, | ||
1488 | "ELS cmd cmpl: status:x%x/x%x did:x%x", | ||
1489 | irsp->ulpStatus, irsp->un.ulpWord[4], | ||
1490 | irsp->un.elsreq64.remoteID); | ||
1491 | |||
1452 | /* ELS cmd tag <ulpIoTag> completes */ | 1492 | /* ELS cmd tag <ulpIoTag> completes */ |
1453 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 1493 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
1454 | "%d (%d):0106 ELS cmd tag x%x completes Data: x%x x%x " | 1494 | "%d (%d):0106 ELS cmd tag x%x completes Data: x%x x%x " |
@@ -1502,6 +1542,10 @@ lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) | |||
1502 | memset(pcmd, 0, sizeof(SCR)); | 1542 | memset(pcmd, 0, sizeof(SCR)); |
1503 | ((SCR *) pcmd)->Function = SCR_FUNC_FULL; | 1543 | ((SCR *) pcmd)->Function = SCR_FUNC_FULL; |
1504 | 1544 | ||
1545 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, | ||
1546 | "Issue SCR: did:x%x", | ||
1547 | ndlp->nlp_DID, 0, 0); | ||
1548 | |||
1505 | phba->fc_stat.elsXmitSCR++; | 1549 | phba->fc_stat.elsXmitSCR++; |
1506 | elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; | 1550 | elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; |
1507 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | 1551 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { |
@@ -1569,6 +1613,10 @@ lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry) | |||
1569 | sizeof(struct lpfc_name)); | 1613 | sizeof(struct lpfc_name)); |
1570 | } | 1614 | } |
1571 | 1615 | ||
1616 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, | ||
1617 | "Issue FARPR: did:x%x", | ||
1618 | ndlp->nlp_DID, 0, 0); | ||
1619 | |||
1572 | phba->fc_stat.elsXmitFARPR++; | 1620 | phba->fc_stat.elsXmitFARPR++; |
1573 | elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; | 1621 | elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd; |
1574 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | 1622 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { |
@@ -1763,6 +1811,10 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1763 | return 1; | 1811 | return 1; |
1764 | } | 1812 | } |
1765 | 1813 | ||
1814 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, | ||
1815 | "Retry ELS: wd7:x%x wd4:x%x did:x%x", | ||
1816 | *(((uint32_t *) irsp) + 7), irsp->un.ulpWord[4], ndlp->nlp_DID); | ||
1817 | |||
1766 | switch (irsp->ulpStatus) { | 1818 | switch (irsp->ulpStatus) { |
1767 | case IOSTAT_FCP_RSP_ERROR: | 1819 | case IOSTAT_FCP_RSP_ERROR: |
1768 | case IOSTAT_REMOTE_STOP: | 1820 | case IOSTAT_REMOTE_STOP: |
@@ -1776,10 +1828,6 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1776 | retry = 1; | 1828 | retry = 1; |
1777 | break; | 1829 | break; |
1778 | 1830 | ||
1779 | case IOERR_SEQUENCE_TIMEOUT: | ||
1780 | retry = 1; | ||
1781 | break; | ||
1782 | |||
1783 | case IOERR_ILLEGAL_COMMAND: | 1831 | case IOERR_ILLEGAL_COMMAND: |
1784 | if ((phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) && | 1832 | if ((phba->sli3_options & LPFC_SLI3_VPORT_TEARDOWN) && |
1785 | (cmd == ELS_CMD_FDISC)) { | 1833 | (cmd == ELS_CMD_FDISC)) { |
@@ -1794,10 +1842,18 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1794 | break; | 1842 | break; |
1795 | 1843 | ||
1796 | case IOERR_NO_RESOURCES: | 1844 | case IOERR_NO_RESOURCES: |
1845 | retry = 1; | ||
1846 | if (cmdiocb->retry > 100) | ||
1847 | delay = 100; | ||
1848 | maxretry = 250; | ||
1849 | break; | ||
1850 | |||
1851 | case IOERR_ILLEGAL_FRAME: | ||
1797 | delay = 100; | 1852 | delay = 100; |
1798 | retry = 1; | 1853 | retry = 1; |
1799 | break; | 1854 | break; |
1800 | 1855 | ||
1856 | case IOERR_SEQUENCE_TIMEOUT: | ||
1801 | case IOERR_INVALID_RPI: | 1857 | case IOERR_INVALID_RPI: |
1802 | retry = 1; | 1858 | retry = 1; |
1803 | break; | 1859 | break; |
@@ -1852,7 +1908,8 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1852 | break; | 1908 | break; |
1853 | 1909 | ||
1854 | case LSRJT_LOGICAL_BSY: | 1910 | case LSRJT_LOGICAL_BSY: |
1855 | if (cmd == ELS_CMD_PLOGI) { | 1911 | if ((cmd == ELS_CMD_PLOGI) || |
1912 | (cmd == ELS_CMD_PRLI)) { | ||
1856 | delay = 1000; | 1913 | delay = 1000; |
1857 | maxretry = 48; | 1914 | maxretry = 48; |
1858 | } else if (cmd == ELS_CMD_FDISC) { | 1915 | } else if (cmd == ELS_CMD_FDISC) { |
@@ -1908,7 +1965,11 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1908 | phba->brd_no, vport->vpi, | 1965 | phba->brd_no, vport->vpi, |
1909 | cmd, did, cmdiocb->retry, delay); | 1966 | cmd, did, cmdiocb->retry, delay); |
1910 | 1967 | ||
1911 | if ((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_ADISC)) { | 1968 | if (((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_ADISC)) && |
1969 | ((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) || | ||
1970 | ((irsp->un.ulpWord[4] & 0xff) != IOERR_NO_RESOURCES))) { | ||
1971 | /* Don't reset timer for no resources */ | ||
1972 | |||
1912 | /* If discovery / RSCN timer is running, reset it */ | 1973 | /* If discovery / RSCN timer is running, reset it */ |
1913 | if (timer_pending(&vport->fc_disctmo) || | 1974 | if (timer_pending(&vport->fc_disctmo) || |
1914 | (vport->fc_flag & FC_RSCN_MODE)) | 1975 | (vport->fc_flag & FC_RSCN_MODE)) |
@@ -1928,7 +1989,12 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
1928 | spin_unlock_irq(shost->host_lock); | 1989 | spin_unlock_irq(shost->host_lock); |
1929 | 1990 | ||
1930 | ndlp->nlp_prev_state = ndlp->nlp_state; | 1991 | ndlp->nlp_prev_state = ndlp->nlp_state; |
1931 | lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE); | 1992 | if (cmd == ELS_CMD_PRLI) |
1993 | lpfc_nlp_set_state(vport, ndlp, | ||
1994 | NLP_STE_REG_LOGIN_ISSUE); | ||
1995 | else | ||
1996 | lpfc_nlp_set_state(vport, ndlp, | ||
1997 | NLP_STE_NPR_NODE); | ||
1932 | ndlp->nlp_last_elscmd = cmd; | 1998 | ndlp->nlp_last_elscmd = cmd; |
1933 | 1999 | ||
1934 | return 1; | 2000 | return 1; |
@@ -2015,6 +2081,12 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2015 | { | 2081 | { |
2016 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1; | 2082 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1; |
2017 | struct lpfc_vport *vport = cmdiocb->vport; | 2083 | struct lpfc_vport *vport = cmdiocb->vport; |
2084 | IOCB_t *irsp; | ||
2085 | |||
2086 | irsp = &rspiocb->iocb; | ||
2087 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, | ||
2088 | "ACC LOGO cmpl: status:x%x/x%x did:x%x", | ||
2089 | irsp->ulpStatus, irsp->un.ulpWord[4], ndlp->nlp_DID); | ||
2018 | 2090 | ||
2019 | /* ACC to LOGO completes to NPort <nlp_DID> */ | 2091 | /* ACC to LOGO completes to NPort <nlp_DID> */ |
2020 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 2092 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
@@ -2037,8 +2109,22 @@ lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2037 | return; | 2109 | return; |
2038 | } | 2110 | } |
2039 | 2111 | ||
2112 | void | ||
2113 | lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | ||
2114 | { | ||
2115 | struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1); | ||
2116 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2; | ||
2117 | |||
2118 | pmb->context1 = NULL; | ||
2119 | lpfc_mbuf_free(phba, mp->virt, mp->phys); | ||
2120 | kfree(mp); | ||
2121 | mempool_free(pmb, phba->mbox_mem_pool); | ||
2122 | lpfc_nlp_put(ndlp); | ||
2123 | return; | ||
2124 | } | ||
2125 | |||
2040 | static void | 2126 | static void |
2041 | lpfc_cmpl_els_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | 2127 | lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, |
2042 | struct lpfc_iocbq *rspiocb) | 2128 | struct lpfc_iocbq *rspiocb) |
2043 | { | 2129 | { |
2044 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1; | 2130 | struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1; |
@@ -2066,6 +2152,11 @@ lpfc_cmpl_els_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2066 | goto out; | 2152 | goto out; |
2067 | } | 2153 | } |
2068 | 2154 | ||
2155 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, | ||
2156 | "ACC cmpl: status:x%x/x%x did:x%x", | ||
2157 | irsp->ulpStatus, irsp->un.ulpWord[4], | ||
2158 | irsp->un.rcvels.remoteID); | ||
2159 | |||
2069 | /* ELS response tag <ulpIoTag> completes */ | 2160 | /* ELS response tag <ulpIoTag> completes */ |
2070 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 2161 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
2071 | "%d (%d):0110 ELS response tag x%x completes " | 2162 | "%d (%d):0110 ELS response tag x%x completes " |
@@ -2080,12 +2171,18 @@ lpfc_cmpl_els_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2080 | if ((rspiocb->iocb.ulpStatus == 0) | 2171 | if ((rspiocb->iocb.ulpStatus == 0) |
2081 | && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) { | 2172 | && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) { |
2082 | lpfc_unreg_rpi(vport, ndlp); | 2173 | lpfc_unreg_rpi(vport, ndlp); |
2083 | mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; | ||
2084 | mbox->context2 = lpfc_nlp_get(ndlp); | 2174 | mbox->context2 = lpfc_nlp_get(ndlp); |
2085 | mbox->vport = vport; | 2175 | mbox->vport = vport; |
2086 | ndlp->nlp_prev_state = ndlp->nlp_state; | 2176 | if (ndlp->nlp_flag & NLP_RM_DFLT_RPI) { |
2087 | lpfc_nlp_set_state(vport, ndlp, | 2177 | mbox->mbox_flag |= LPFC_MBX_IMED_UNREG; |
2178 | mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi; | ||
2179 | } | ||
2180 | else { | ||
2181 | mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login; | ||
2182 | ndlp->nlp_prev_state = ndlp->nlp_state; | ||
2183 | lpfc_nlp_set_state(vport, ndlp, | ||
2088 | NLP_STE_REG_LOGIN_ISSUE); | 2184 | NLP_STE_REG_LOGIN_ISSUE); |
2185 | } | ||
2089 | if (lpfc_sli_issue_mbox(phba, mbox, | 2186 | if (lpfc_sli_issue_mbox(phba, mbox, |
2090 | (MBX_NOWAIT | MBX_STOP_IOCB)) | 2187 | (MBX_NOWAIT | MBX_STOP_IOCB)) |
2091 | != MBX_NOT_FINISHED) { | 2188 | != MBX_NOT_FINISHED) { |
@@ -2095,15 +2192,11 @@ lpfc_cmpl_els_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2095 | /* NOTE: we should have messages for unsuccessful | 2192 | /* NOTE: we should have messages for unsuccessful |
2096 | reglogin */ | 2193 | reglogin */ |
2097 | } else { | 2194 | } else { |
2098 | /* Do not call NO_LIST for lpfc_els_abort'ed ELS cmds */ | 2195 | /* Do not drop node for lpfc_els_abort'ed ELS cmds */ |
2099 | if (!((irsp->ulpStatus == IOSTAT_LOCAL_REJECT) && | 2196 | if (!lpfc_error_lost_link(irsp) && |
2100 | ((irsp->un.ulpWord[4] == IOERR_SLI_ABORTED) || | 2197 | ndlp->nlp_flag & NLP_ACC_REGLOGIN) { |
2101 | (irsp->un.ulpWord[4] == IOERR_LINK_DOWN) || | 2198 | lpfc_drop_node(vport, ndlp); |
2102 | (irsp->un.ulpWord[4] == IOERR_SLI_DOWN)))) { | 2199 | ndlp = NULL; |
2103 | if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { | ||
2104 | lpfc_drop_node(vport, ndlp); | ||
2105 | ndlp = NULL; | ||
2106 | } | ||
2107 | } | 2200 | } |
2108 | } | 2201 | } |
2109 | mp = (struct lpfc_dmabuf *) mbox->context1; | 2202 | mp = (struct lpfc_dmabuf *) mbox->context1; |
@@ -2116,7 +2209,7 @@ lpfc_cmpl_els_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
2116 | out: | 2209 | out: |
2117 | if (ndlp) { | 2210 | if (ndlp) { |
2118 | spin_lock_irq(shost->host_lock); | 2211 | spin_lock_irq(shost->host_lock); |
2119 | ndlp->nlp_flag &= ~NLP_ACC_REGLOGIN; | 2212 | ndlp->nlp_flag &= ~(NLP_ACC_REGLOGIN | NLP_RM_DFLT_RPI); |
2120 | spin_unlock_irq(shost->host_lock); | 2213 | spin_unlock_irq(shost->host_lock); |
2121 | } | 2214 | } |
2122 | lpfc_els_free_iocb(phba, cmdiocb); | 2215 | lpfc_els_free_iocb(phba, cmdiocb); |
@@ -2161,6 +2254,10 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, | |||
2161 | pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt); | 2254 | pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt); |
2162 | *((uint32_t *) (pcmd)) = ELS_CMD_ACC; | 2255 | *((uint32_t *) (pcmd)) = ELS_CMD_ACC; |
2163 | pcmd += sizeof(uint32_t); | 2256 | pcmd += sizeof(uint32_t); |
2257 | |||
2258 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, | ||
2259 | "Issue ACC: did:x%x flg:x%x", | ||
2260 | ndlp->nlp_DID, ndlp->nlp_flag, 0); | ||
2164 | break; | 2261 | break; |
2165 | case ELS_CMD_PLOGI: | 2262 | case ELS_CMD_PLOGI: |
2166 | cmdsize = (sizeof(struct serv_parm) + sizeof(uint32_t)); | 2263 | cmdsize = (sizeof(struct serv_parm) + sizeof(uint32_t)); |
@@ -2179,6 +2276,10 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, | |||
2179 | *((uint32_t *) (pcmd)) = ELS_CMD_ACC; | 2276 | *((uint32_t *) (pcmd)) = ELS_CMD_ACC; |
2180 | pcmd += sizeof(uint32_t); | 2277 | pcmd += sizeof(uint32_t); |
2181 | memcpy(pcmd, &vport->fc_sparam, sizeof(struct serv_parm)); | 2278 | memcpy(pcmd, &vport->fc_sparam, sizeof(struct serv_parm)); |
2279 | |||
2280 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, | ||
2281 | "Issue ACC PLOGI: did:x%x flg:x%x", | ||
2282 | ndlp->nlp_DID, ndlp->nlp_flag, 0); | ||
2182 | break; | 2283 | break; |
2183 | case ELS_CMD_PRLO: | 2284 | case ELS_CMD_PRLO: |
2184 | cmdsize = sizeof(uint32_t) + sizeof(PRLO); | 2285 | cmdsize = sizeof(uint32_t) + sizeof(PRLO); |
@@ -2196,6 +2297,10 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, | |||
2196 | *((uint32_t *) (pcmd)) = ELS_CMD_PRLO_ACC; | 2297 | *((uint32_t *) (pcmd)) = ELS_CMD_PRLO_ACC; |
2197 | els_pkt_ptr = (ELS_PKT *) pcmd; | 2298 | els_pkt_ptr = (ELS_PKT *) pcmd; |
2198 | els_pkt_ptr->un.prlo.acceptRspCode = PRLO_REQ_EXECUTED; | 2299 | els_pkt_ptr->un.prlo.acceptRspCode = PRLO_REQ_EXECUTED; |
2300 | |||
2301 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, | ||
2302 | "Issue ACC PRLO: did:x%x flg:x%x", | ||
2303 | ndlp->nlp_DID, ndlp->nlp_flag, 0); | ||
2199 | break; | 2304 | break; |
2200 | default: | 2305 | default: |
2201 | return 1; | 2306 | return 1; |
@@ -2220,7 +2325,7 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, | |||
2220 | spin_unlock_irq(shost->host_lock); | 2325 | spin_unlock_irq(shost->host_lock); |
2221 | elsiocb->iocb_cmpl = lpfc_cmpl_els_logo_acc; | 2326 | elsiocb->iocb_cmpl = lpfc_cmpl_els_logo_acc; |
2222 | } else { | 2327 | } else { |
2223 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; | 2328 | elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; |
2224 | } | 2329 | } |
2225 | 2330 | ||
2226 | phba->fc_stat.elsXmitACC++; | 2331 | phba->fc_stat.elsXmitACC++; |
@@ -2234,7 +2339,8 @@ lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag, | |||
2234 | 2339 | ||
2235 | int | 2340 | int |
2236 | lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, | 2341 | lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, |
2237 | struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp) | 2342 | struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp, |
2343 | LPFC_MBOXQ_t *mbox) | ||
2238 | { | 2344 | { |
2239 | struct lpfc_hba *phba = vport->phba; | 2345 | struct lpfc_hba *phba = vport->phba; |
2240 | IOCB_t *icmd; | 2346 | IOCB_t *icmd; |
@@ -2264,6 +2370,11 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, | |||
2264 | pcmd += sizeof(uint32_t); | 2370 | pcmd += sizeof(uint32_t); |
2265 | *((uint32_t *) (pcmd)) = rejectError; | 2371 | *((uint32_t *) (pcmd)) = rejectError; |
2266 | 2372 | ||
2373 | if (mbox) { | ||
2374 | elsiocb->context_un.mbox = mbox; | ||
2375 | elsiocb->context1 = lpfc_nlp_get(ndlp); | ||
2376 | } | ||
2377 | |||
2267 | /* Xmit ELS RJT <err> response tag <ulpIoTag> */ | 2378 | /* Xmit ELS RJT <err> response tag <ulpIoTag> */ |
2268 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, | 2379 | lpfc_printf_log(phba, KERN_INFO, LOG_ELS, |
2269 | "%d (%d):0129 Xmit ELS RJT x%x response tag x%x " | 2380 | "%d (%d):0129 Xmit ELS RJT x%x response tag x%x " |
@@ -2273,8 +2384,12 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, | |||
2273 | elsiocb->iocb.ulpContext, ndlp->nlp_DID, | 2384 | elsiocb->iocb.ulpContext, ndlp->nlp_DID, |
2274 | ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); | 2385 | ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); |
2275 | 2386 | ||
2387 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, | ||
2388 | "Issue LS_RJT: did:x%x flg:x%x err:x%x", | ||
2389 | ndlp->nlp_DID, ndlp->nlp_flag, rejectError); | ||
2390 | |||
2276 | phba->fc_stat.elsXmitLSRJT++; | 2391 | phba->fc_stat.elsXmitLSRJT++; |
2277 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; | 2392 | elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; |
2278 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); | 2393 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); |
2279 | if (rc == IOCB_ERROR) { | 2394 | if (rc == IOCB_ERROR) { |
2280 | lpfc_els_free_iocb(phba, elsiocb); | 2395 | lpfc_els_free_iocb(phba, elsiocb); |
@@ -2326,8 +2441,12 @@ lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, | |||
2326 | memcpy(&ap->nodeName, &vport->fc_nodename, sizeof(struct lpfc_name)); | 2441 | memcpy(&ap->nodeName, &vport->fc_nodename, sizeof(struct lpfc_name)); |
2327 | ap->DID = be32_to_cpu(vport->fc_myDID); | 2442 | ap->DID = be32_to_cpu(vport->fc_myDID); |
2328 | 2443 | ||
2444 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, | ||
2445 | "Issue ACC ADISC: did:x%x flg:x%x", | ||
2446 | ndlp->nlp_DID, ndlp->nlp_flag, 0); | ||
2447 | |||
2329 | phba->fc_stat.elsXmitACC++; | 2448 | phba->fc_stat.elsXmitACC++; |
2330 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; | 2449 | elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; |
2331 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); | 2450 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); |
2332 | if (rc == IOCB_ERROR) { | 2451 | if (rc == IOCB_ERROR) { |
2333 | lpfc_els_free_iocb(phba, elsiocb); | 2452 | lpfc_els_free_iocb(phba, elsiocb); |
@@ -2401,8 +2520,12 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, | |||
2401 | npr->prliType = PRLI_FCP_TYPE; | 2520 | npr->prliType = PRLI_FCP_TYPE; |
2402 | npr->initiatorFunc = 1; | 2521 | npr->initiatorFunc = 1; |
2403 | 2522 | ||
2523 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, | ||
2524 | "Issue ACC PRLI: did:x%x flg:x%x", | ||
2525 | ndlp->nlp_DID, ndlp->nlp_flag, 0); | ||
2526 | |||
2404 | phba->fc_stat.elsXmitACC++; | 2527 | phba->fc_stat.elsXmitACC++; |
2405 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; | 2528 | elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; |
2406 | 2529 | ||
2407 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); | 2530 | rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0); |
2408 | if (rc == IOCB_ERROR) { | 2531 | if (rc == IOCB_ERROR) { |
@@ -2479,8 +2602,12 @@ lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format, | |||
2479 | break; | 2602 | break; |
2480 | } | 2603 | } |
2481 | 2604 | ||
2605 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, | ||
2606 | "Issue ACC RNID: did:x%x flg:x%x", | ||
2607 | ndlp->nlp_DID, ndlp->nlp_flag, 0); | ||
2608 | |||
2482 | phba->fc_stat.elsXmitACC++; | 2609 | phba->fc_stat.elsXmitACC++; |
2483 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; | 2610 | elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; |
2484 | lpfc_nlp_put(ndlp); | 2611 | lpfc_nlp_put(ndlp); |
2485 | elsiocb->context1 = NULL; /* Don't need ndlp for cmpl, | 2612 | elsiocb->context1 = NULL; /* Don't need ndlp for cmpl, |
2486 | * it could be freed */ | 2613 | * it could be freed */ |
@@ -2703,6 +2830,10 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
2703 | * Discovery processing will satisfy it. | 2830 | * Discovery processing will satisfy it. |
2704 | */ | 2831 | */ |
2705 | if (vport->port_state <= LPFC_NS_QRY) { | 2832 | if (vport->port_state <= LPFC_NS_QRY) { |
2833 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | ||
2834 | "RCV RSCN ignore: did:x%x/ste:x%x flg:x%x", | ||
2835 | ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag); | ||
2836 | |||
2706 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, | 2837 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL, |
2707 | newnode); | 2838 | newnode); |
2708 | return 0; | 2839 | return 0; |
@@ -2734,6 +2865,12 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
2734 | "%d (%d):0214 Ignore RSCN Data: x%x x%x x%x x%x\n", | 2865 | "%d (%d):0214 Ignore RSCN Data: x%x x%x x%x x%x\n", |
2735 | phba->brd_no, vport->vpi, vport->fc_flag, payload_len, | 2866 | phba->brd_no, vport->vpi, vport->fc_flag, payload_len, |
2736 | *lp, rscn_cnt); | 2867 | *lp, rscn_cnt); |
2868 | |||
2869 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | ||
2870 | "RCV RSCN vport: did:x%x/ste:x%x flg:x%x", | ||
2871 | ndlp->nlp_DID, vport->port_state, | ||
2872 | ndlp->nlp_flag); | ||
2873 | |||
2737 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, | 2874 | lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, |
2738 | ndlp, NULL, newnode); | 2875 | ndlp, NULL, newnode); |
2739 | return 0; | 2876 | return 0; |
@@ -2744,6 +2881,10 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
2744 | * RSCN payload buffer, cmdiocb->context2 to process later. | 2881 | * RSCN payload buffer, cmdiocb->context2 to process later. |
2745 | */ | 2882 | */ |
2746 | if (vport->fc_flag & (FC_RSCN_MODE | FC_NDISC_ACTIVE)) { | 2883 | if (vport->fc_flag & (FC_RSCN_MODE | FC_NDISC_ACTIVE)) { |
2884 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | ||
2885 | "RCV RSCN defer: did:x%x/ste:x%x flg:x%x", | ||
2886 | ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag); | ||
2887 | |||
2747 | vport->fc_flag |= FC_RSCN_DEFERRED; | 2888 | vport->fc_flag |= FC_RSCN_DEFERRED; |
2748 | if ((rscn_cnt < FC_MAX_HOLD_RSCN) && | 2889 | if ((rscn_cnt < FC_MAX_HOLD_RSCN) && |
2749 | !(vport->fc_flag & FC_RSCN_DISCOVERY)) { | 2890 | !(vport->fc_flag & FC_RSCN_DISCOVERY)) { |
@@ -2798,6 +2939,10 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
2798 | return 0; | 2939 | return 0; |
2799 | } | 2940 | } |
2800 | 2941 | ||
2942 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | ||
2943 | "RCV RSCN: did:x%x/ste:x%x flg:x%x", | ||
2944 | ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag); | ||
2945 | |||
2801 | spin_lock_irq(shost->host_lock); | 2946 | spin_lock_irq(shost->host_lock); |
2802 | vport->fc_flag |= FC_RSCN_MODE; | 2947 | vport->fc_flag |= FC_RSCN_MODE; |
2803 | spin_unlock_irq(shost->host_lock); | 2948 | spin_unlock_irq(shost->host_lock); |
@@ -2958,7 +3103,8 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
2958 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 3103 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
2959 | stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; | 3104 | stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS; |
2960 | stat.un.b.vendorUnique = 0; | 3105 | stat.un.b.vendorUnique = 0; |
2961 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp); | 3106 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, |
3107 | NULL); | ||
2962 | return 1; | 3108 | return 1; |
2963 | } | 3109 | } |
2964 | 3110 | ||
@@ -3001,7 +3147,8 @@ lpfc_els_rcv_rnid(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3001 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 3147 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
3002 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; | 3148 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; |
3003 | stat.un.b.vendorUnique = 0; | 3149 | stat.un.b.vendorUnique = 0; |
3004 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp); | 3150 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, |
3151 | NULL); | ||
3005 | } | 3152 | } |
3006 | return 0; | 3153 | return 0; |
3007 | } | 3154 | } |
@@ -3017,7 +3164,7 @@ lpfc_els_rcv_lirr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3017 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 3164 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
3018 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; | 3165 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; |
3019 | stat.un.b.vendorUnique = 0; | 3166 | stat.un.b.vendorUnique = 0; |
3020 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp); | 3167 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL); |
3021 | return 0; | 3168 | return 0; |
3022 | } | 3169 | } |
3023 | 3170 | ||
@@ -3089,7 +3236,7 @@ lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) | |||
3089 | elsiocb->iocb.ulpContext, ndlp->nlp_DID, | 3236 | elsiocb->iocb.ulpContext, ndlp->nlp_DID, |
3090 | ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); | 3237 | ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); |
3091 | 3238 | ||
3092 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; | 3239 | elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; |
3093 | phba->fc_stat.elsXmitACC++; | 3240 | phba->fc_stat.elsXmitACC++; |
3094 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) | 3241 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) |
3095 | lpfc_els_free_iocb(phba, elsiocb); | 3242 | lpfc_els_free_iocb(phba, elsiocb); |
@@ -3114,7 +3261,8 @@ lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3114 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 3261 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
3115 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; | 3262 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; |
3116 | stat.un.b.vendorUnique = 0; | 3263 | stat.un.b.vendorUnique = 0; |
3117 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp); | 3264 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, |
3265 | NULL); | ||
3118 | } | 3266 | } |
3119 | 3267 | ||
3120 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | 3268 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; |
@@ -3150,7 +3298,7 @@ lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3150 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 3298 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
3151 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; | 3299 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; |
3152 | stat.un.b.vendorUnique = 0; | 3300 | stat.un.b.vendorUnique = 0; |
3153 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp); | 3301 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL); |
3154 | return 0; | 3302 | return 0; |
3155 | } | 3303 | } |
3156 | 3304 | ||
@@ -3202,7 +3350,7 @@ lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize, | |||
3202 | elsiocb->iocb.ulpContext, ndlp->nlp_DID, | 3350 | elsiocb->iocb.ulpContext, ndlp->nlp_DID, |
3203 | ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); | 3351 | ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); |
3204 | 3352 | ||
3205 | elsiocb->iocb_cmpl = lpfc_cmpl_els_acc; | 3353 | elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp; |
3206 | 3354 | ||
3207 | phba->fc_stat.elsXmitACC++; | 3355 | phba->fc_stat.elsXmitACC++; |
3208 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { | 3356 | if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) { |
@@ -3229,7 +3377,8 @@ lpfc_els_rcv_rpl(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, | |||
3229 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | 3377 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; |
3230 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; | 3378 | stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA; |
3231 | stat.un.b.vendorUnique = 0; | 3379 | stat.un.b.vendorUnique = 0; |
3232 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp); | 3380 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, |
3381 | NULL); | ||
3233 | } | 3382 | } |
3234 | 3383 | ||
3235 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; | 3384 | pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; |
@@ -3538,9 +3687,6 @@ lpfc_els_flush_cmd(struct lpfc_vport *vport) | |||
3538 | struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; | 3687 | struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING]; |
3539 | struct lpfc_iocbq *tmp_iocb, *piocb; | 3688 | struct lpfc_iocbq *tmp_iocb, *piocb; |
3540 | IOCB_t *cmd = NULL; | 3689 | IOCB_t *cmd = NULL; |
3541 | struct lpfc_dmabuf *pcmd; | ||
3542 | uint32_t *elscmd; | ||
3543 | uint32_t els_command; | ||
3544 | 3690 | ||
3545 | lpfc_fabric_abort_vport(vport); | 3691 | lpfc_fabric_abort_vport(vport); |
3546 | 3692 | ||
@@ -3559,10 +3705,6 @@ lpfc_els_flush_cmd(struct lpfc_vport *vport) | |||
3559 | cmd->ulpCommand == CMD_ABORT_XRI_CN) | 3705 | cmd->ulpCommand == CMD_ABORT_XRI_CN) |
3560 | continue; | 3706 | continue; |
3561 | 3707 | ||
3562 | pcmd = (struct lpfc_dmabuf *) piocb->context2; | ||
3563 | elscmd = (uint32_t *) (pcmd->virt); | ||
3564 | els_command = *elscmd; | ||
3565 | |||
3566 | if (piocb->vport != vport) | 3708 | if (piocb->vport != vport) |
3567 | continue; | 3709 | continue; |
3568 | 3710 | ||
@@ -3618,8 +3760,13 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3618 | if ((phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) == 0) | 3760 | if ((phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) == 0) |
3619 | lpfc_post_buffer(phba, pring, 1, 1); | 3761 | lpfc_post_buffer(phba, pring, 1, 1); |
3620 | 3762 | ||
3621 | if (icmd->ulpStatus) | 3763 | did = icmd->un.rcvels.remoteID; |
3764 | if (icmd->ulpStatus) { | ||
3765 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | ||
3766 | "RCV Unsol ELS: status:x%x/x%x did:x%x", | ||
3767 | icmd->ulpStatus, icmd->un.ulpWord[4], did); | ||
3622 | goto dropit; | 3768 | goto dropit; |
3769 | } | ||
3623 | 3770 | ||
3624 | /* Check to see if link went down during discovery */ | 3771 | /* Check to see if link went down during discovery */ |
3625 | if (lpfc_els_chk_latt(vport)) | 3772 | if (lpfc_els_chk_latt(vport)) |
@@ -3629,7 +3776,6 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3629 | if (vport->load_flag & FC_UNLOADING) | 3776 | if (vport->load_flag & FC_UNLOADING) |
3630 | goto dropit; | 3777 | goto dropit; |
3631 | 3778 | ||
3632 | did = icmd->un.rcvels.remoteID; | ||
3633 | ndlp = lpfc_findnode_did(vport, did); | 3779 | ndlp = lpfc_findnode_did(vport, did); |
3634 | if (!ndlp) { | 3780 | if (!ndlp) { |
3635 | /* Cannot find existing Fabric ndlp, so allocate a new one */ | 3781 | /* Cannot find existing Fabric ndlp, so allocate a new one */ |
@@ -3662,35 +3808,51 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3662 | 3808 | ||
3663 | switch (cmd) { | 3809 | switch (cmd) { |
3664 | case ELS_CMD_PLOGI: | 3810 | case ELS_CMD_PLOGI: |
3811 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | ||
3812 | "RCV PLOGI: did:x%x/ste:x%x flg:x%x", | ||
3813 | did, vport->port_state, ndlp->nlp_flag); | ||
3814 | |||
3665 | phba->fc_stat.elsRcvPLOGI++; | 3815 | phba->fc_stat.elsRcvPLOGI++; |
3666 | if ((vport->port_state < LPFC_DISC_AUTH) || | 3816 | ndlp = lpfc_plogi_confirm_nport(phba, payload, ndlp); |
3667 | ((vport->port_type == LPFC_NPIV_PORT && | 3817 | |
3668 | phba->cfg_vport_restrict_login))) { | 3818 | if (vport->port_state < LPFC_DISC_AUTH) { |
3669 | rjt_err = 2; | 3819 | rjt_err = LSRJT_UNABLE_TPC; |
3670 | break; | 3820 | break; |
3671 | } | 3821 | } |
3672 | ndlp = lpfc_plogi_confirm_nport(phba, payload, ndlp); | ||
3673 | lpfc_disc_state_machine(vport, ndlp, elsiocb, | 3822 | lpfc_disc_state_machine(vport, ndlp, elsiocb, |
3674 | NLP_EVT_RCV_PLOGI); | 3823 | NLP_EVT_RCV_PLOGI); |
3824 | |||
3675 | break; | 3825 | break; |
3676 | case ELS_CMD_FLOGI: | 3826 | case ELS_CMD_FLOGI: |
3827 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | ||
3828 | "RCV FLOGI: did:x%x/ste:x%x flg:x%x", | ||
3829 | did, vport->port_state, ndlp->nlp_flag); | ||
3830 | |||
3677 | phba->fc_stat.elsRcvFLOGI++; | 3831 | phba->fc_stat.elsRcvFLOGI++; |
3678 | lpfc_els_rcv_flogi(vport, elsiocb, ndlp, newnode); | 3832 | lpfc_els_rcv_flogi(vport, elsiocb, ndlp, newnode); |
3679 | if (newnode) | 3833 | if (newnode) |
3680 | lpfc_drop_node(vport, ndlp); | 3834 | lpfc_drop_node(vport, ndlp); |
3681 | break; | 3835 | break; |
3682 | case ELS_CMD_LOGO: | 3836 | case ELS_CMD_LOGO: |
3837 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | ||
3838 | "RCV LOGO: did:x%x/ste:x%x flg:x%x", | ||
3839 | did, vport->port_state, ndlp->nlp_flag); | ||
3840 | |||
3683 | phba->fc_stat.elsRcvLOGO++; | 3841 | phba->fc_stat.elsRcvLOGO++; |
3684 | if (vport->port_state < LPFC_DISC_AUTH) { | 3842 | if (vport->port_state < LPFC_DISC_AUTH) { |
3685 | rjt_err = 1; | 3843 | rjt_err = LSRJT_UNABLE_TPC; |
3686 | break; | 3844 | break; |
3687 | } | 3845 | } |
3688 | lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_LOGO); | 3846 | lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_LOGO); |
3689 | break; | 3847 | break; |
3690 | case ELS_CMD_PRLO: | 3848 | case ELS_CMD_PRLO: |
3849 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | ||
3850 | "RCV PRLO: did:x%x/ste:x%x flg:x%x", | ||
3851 | did, vport->port_state, ndlp->nlp_flag); | ||
3852 | |||
3691 | phba->fc_stat.elsRcvPRLO++; | 3853 | phba->fc_stat.elsRcvPRLO++; |
3692 | if (vport->port_state < LPFC_DISC_AUTH) { | 3854 | if (vport->port_state < LPFC_DISC_AUTH) { |
3693 | rjt_err = 1; | 3855 | rjt_err = LSRJT_UNABLE_TPC; |
3694 | break; | 3856 | break; |
3695 | } | 3857 | } |
3696 | lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLO); | 3858 | lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLO); |
@@ -3702,70 +3864,114 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3702 | lpfc_drop_node(vport, ndlp); | 3864 | lpfc_drop_node(vport, ndlp); |
3703 | break; | 3865 | break; |
3704 | case ELS_CMD_ADISC: | 3866 | case ELS_CMD_ADISC: |
3867 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | ||
3868 | "RCV ADISC: did:x%x/ste:x%x flg:x%x", | ||
3869 | did, vport->port_state, ndlp->nlp_flag); | ||
3870 | |||
3705 | phba->fc_stat.elsRcvADISC++; | 3871 | phba->fc_stat.elsRcvADISC++; |
3706 | if (vport->port_state < LPFC_DISC_AUTH) { | 3872 | if (vport->port_state < LPFC_DISC_AUTH) { |
3707 | rjt_err = 1; | 3873 | rjt_err = LSRJT_UNABLE_TPC; |
3708 | break; | 3874 | break; |
3709 | } | 3875 | } |
3710 | lpfc_disc_state_machine(vport, ndlp, elsiocb, | 3876 | lpfc_disc_state_machine(vport, ndlp, elsiocb, |
3711 | NLP_EVT_RCV_ADISC); | 3877 | NLP_EVT_RCV_ADISC); |
3712 | break; | 3878 | break; |
3713 | case ELS_CMD_PDISC: | 3879 | case ELS_CMD_PDISC: |
3880 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | ||
3881 | "RCV PDISC: did:x%x/ste:x%x flg:x%x", | ||
3882 | did, vport->port_state, ndlp->nlp_flag); | ||
3883 | |||
3714 | phba->fc_stat.elsRcvPDISC++; | 3884 | phba->fc_stat.elsRcvPDISC++; |
3715 | if (vport->port_state < LPFC_DISC_AUTH) { | 3885 | if (vport->port_state < LPFC_DISC_AUTH) { |
3716 | rjt_err = 1; | 3886 | rjt_err = LSRJT_UNABLE_TPC; |
3717 | break; | 3887 | break; |
3718 | } | 3888 | } |
3719 | lpfc_disc_state_machine(vport, ndlp, elsiocb, | 3889 | lpfc_disc_state_machine(vport, ndlp, elsiocb, |
3720 | NLP_EVT_RCV_PDISC); | 3890 | NLP_EVT_RCV_PDISC); |
3721 | break; | 3891 | break; |
3722 | case ELS_CMD_FARPR: | 3892 | case ELS_CMD_FARPR: |
3893 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | ||
3894 | "RCV FARPR: did:x%x/ste:x%x flg:x%x", | ||
3895 | did, vport->port_state, ndlp->nlp_flag); | ||
3896 | |||
3723 | phba->fc_stat.elsRcvFARPR++; | 3897 | phba->fc_stat.elsRcvFARPR++; |
3724 | lpfc_els_rcv_farpr(vport, elsiocb, ndlp); | 3898 | lpfc_els_rcv_farpr(vport, elsiocb, ndlp); |
3725 | break; | 3899 | break; |
3726 | case ELS_CMD_FARP: | 3900 | case ELS_CMD_FARP: |
3901 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | ||
3902 | "RCV FARP: did:x%x/ste:x%x flg:x%x", | ||
3903 | did, vport->port_state, ndlp->nlp_flag); | ||
3904 | |||
3727 | phba->fc_stat.elsRcvFARP++; | 3905 | phba->fc_stat.elsRcvFARP++; |
3728 | lpfc_els_rcv_farp(vport, elsiocb, ndlp); | 3906 | lpfc_els_rcv_farp(vport, elsiocb, ndlp); |
3729 | break; | 3907 | break; |
3730 | case ELS_CMD_FAN: | 3908 | case ELS_CMD_FAN: |
3909 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | ||
3910 | "RCV FAN: did:x%x/ste:x%x flg:x%x", | ||
3911 | did, vport->port_state, ndlp->nlp_flag); | ||
3912 | |||
3731 | phba->fc_stat.elsRcvFAN++; | 3913 | phba->fc_stat.elsRcvFAN++; |
3732 | lpfc_els_rcv_fan(vport, elsiocb, ndlp); | 3914 | lpfc_els_rcv_fan(vport, elsiocb, ndlp); |
3733 | break; | 3915 | break; |
3734 | case ELS_CMD_PRLI: | 3916 | case ELS_CMD_PRLI: |
3917 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | ||
3918 | "RCV PRLI: did:x%x/ste:x%x flg:x%x", | ||
3919 | did, vport->port_state, ndlp->nlp_flag); | ||
3920 | |||
3735 | phba->fc_stat.elsRcvPRLI++; | 3921 | phba->fc_stat.elsRcvPRLI++; |
3736 | if (vport->port_state < LPFC_DISC_AUTH) { | 3922 | if (vport->port_state < LPFC_DISC_AUTH) { |
3737 | rjt_err = 1; | 3923 | rjt_err = LSRJT_UNABLE_TPC; |
3738 | break; | 3924 | break; |
3739 | } | 3925 | } |
3740 | lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLI); | 3926 | lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLI); |
3741 | break; | 3927 | break; |
3742 | case ELS_CMD_LIRR: | 3928 | case ELS_CMD_LIRR: |
3929 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | ||
3930 | "RCV LIRR: did:x%x/ste:x%x flg:x%x", | ||
3931 | did, vport->port_state, ndlp->nlp_flag); | ||
3932 | |||
3743 | phba->fc_stat.elsRcvLIRR++; | 3933 | phba->fc_stat.elsRcvLIRR++; |
3744 | lpfc_els_rcv_lirr(vport, elsiocb, ndlp); | 3934 | lpfc_els_rcv_lirr(vport, elsiocb, ndlp); |
3745 | if (newnode) | 3935 | if (newnode) |
3746 | lpfc_drop_node(vport, ndlp); | 3936 | lpfc_drop_node(vport, ndlp); |
3747 | break; | 3937 | break; |
3748 | case ELS_CMD_RPS: | 3938 | case ELS_CMD_RPS: |
3939 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | ||
3940 | "RCV RPS: did:x%x/ste:x%x flg:x%x", | ||
3941 | did, vport->port_state, ndlp->nlp_flag); | ||
3942 | |||
3749 | phba->fc_stat.elsRcvRPS++; | 3943 | phba->fc_stat.elsRcvRPS++; |
3750 | lpfc_els_rcv_rps(vport, elsiocb, ndlp); | 3944 | lpfc_els_rcv_rps(vport, elsiocb, ndlp); |
3751 | if (newnode) | 3945 | if (newnode) |
3752 | lpfc_drop_node(vport, ndlp); | 3946 | lpfc_drop_node(vport, ndlp); |
3753 | break; | 3947 | break; |
3754 | case ELS_CMD_RPL: | 3948 | case ELS_CMD_RPL: |
3949 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | ||
3950 | "RCV RPL: did:x%x/ste:x%x flg:x%x", | ||
3951 | did, vport->port_state, ndlp->nlp_flag); | ||
3952 | |||
3755 | phba->fc_stat.elsRcvRPL++; | 3953 | phba->fc_stat.elsRcvRPL++; |
3756 | lpfc_els_rcv_rpl(vport, elsiocb, ndlp); | 3954 | lpfc_els_rcv_rpl(vport, elsiocb, ndlp); |
3757 | if (newnode) | 3955 | if (newnode) |
3758 | lpfc_drop_node(vport, ndlp); | 3956 | lpfc_drop_node(vport, ndlp); |
3759 | break; | 3957 | break; |
3760 | case ELS_CMD_RNID: | 3958 | case ELS_CMD_RNID: |
3959 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | ||
3960 | "RCV RNID: did:x%x/ste:x%x flg:x%x", | ||
3961 | did, vport->port_state, ndlp->nlp_flag); | ||
3962 | |||
3761 | phba->fc_stat.elsRcvRNID++; | 3963 | phba->fc_stat.elsRcvRNID++; |
3762 | lpfc_els_rcv_rnid(vport, elsiocb, ndlp); | 3964 | lpfc_els_rcv_rnid(vport, elsiocb, ndlp); |
3763 | if (newnode) | 3965 | if (newnode) |
3764 | lpfc_drop_node(vport, ndlp); | 3966 | lpfc_drop_node(vport, ndlp); |
3765 | break; | 3967 | break; |
3766 | default: | 3968 | default: |
3969 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | ||
3970 | "RCV ELS cmd: cmd:x%x did:x%x/ste:x%x", | ||
3971 | cmd, did, vport->port_state); | ||
3972 | |||
3767 | /* Unsupported ELS command, reject */ | 3973 | /* Unsupported ELS command, reject */ |
3768 | rjt_err = 2; | 3974 | rjt_err = LSRJT_INVALID_CMD; |
3769 | 3975 | ||
3770 | /* Unknown ELS command <elsCmd> received from NPORT <did> */ | 3976 | /* Unknown ELS command <elsCmd> received from NPORT <did> */ |
3771 | lpfc_printf_log(phba, KERN_ERR, LOG_ELS, | 3977 | lpfc_printf_log(phba, KERN_ERR, LOG_ELS, |
@@ -3780,12 +3986,10 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
3780 | /* check if need to LS_RJT received ELS cmd */ | 3986 | /* check if need to LS_RJT received ELS cmd */ |
3781 | if (rjt_err) { | 3987 | if (rjt_err) { |
3782 | memset(&stat, 0, sizeof(stat)); | 3988 | memset(&stat, 0, sizeof(stat)); |
3783 | if (rjt_err == 1) | 3989 | stat.un.b.lsRjtRsnCode = rjt_err; |
3784 | stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC; | ||
3785 | else | ||
3786 | stat.un.b.lsRjtRsnCode = LSRJT_INVALID_CMD; | ||
3787 | stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; | 3990 | stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; |
3788 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, elsiocb, ndlp); | 3991 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, elsiocb, ndlp, |
3992 | NULL); | ||
3789 | if (newnode) | 3993 | if (newnode) |
3790 | lpfc_drop_node(vport, ndlp); | 3994 | lpfc_drop_node(vport, ndlp); |
3791 | } | 3995 | } |
@@ -4044,6 +4248,10 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
4044 | lpfc_set_disctmo(piocb->vport); | 4248 | lpfc_set_disctmo(piocb->vport); |
4045 | } | 4249 | } |
4046 | 4250 | ||
4251 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, | ||
4252 | "FDISC cmpl: status:x%x/x%x prevdid:x%x", | ||
4253 | irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_prevDID); | ||
4254 | |||
4047 | if (irsp->ulpStatus) { | 4255 | if (irsp->ulpStatus) { |
4048 | /* Check for retry */ | 4256 | /* Check for retry */ |
4049 | if (lpfc_els_retry(phba, cmdiocb, rspiocb)) | 4257 | if (lpfc_els_retry(phba, cmdiocb, rspiocb)) |
@@ -4054,6 +4262,7 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
4054 | "%d (%d):0124 FDISC failed. (%d/%d)\n", | 4262 | "%d (%d):0124 FDISC failed. (%d/%d)\n", |
4055 | phba->brd_no, vport->vpi, | 4263 | phba->brd_no, vport->vpi, |
4056 | irsp->ulpStatus, irsp->un.ulpWord[4]); | 4264 | irsp->ulpStatus, irsp->un.ulpWord[4]); |
4265 | |||
4057 | if (vport->fc_vport->vport_state == FC_VPORT_INITIALIZING) | 4266 | if (vport->fc_vport->vport_state == FC_VPORT_INITIALIZING) |
4058 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 4267 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
4059 | 4268 | ||
@@ -4113,14 +4322,11 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
4113 | uint16_t cmdsize; | 4322 | uint16_t cmdsize; |
4114 | int did = ndlp->nlp_DID; | 4323 | int did = ndlp->nlp_DID; |
4115 | int rc; | 4324 | int rc; |
4116 | int new_ndlp = 0; | ||
4117 | 4325 | ||
4118 | cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm)); | 4326 | cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm)); |
4119 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did, | 4327 | elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did, |
4120 | ELS_CMD_FDISC); | 4328 | ELS_CMD_FDISC); |
4121 | if (!elsiocb) { | 4329 | if (!elsiocb) { |
4122 | if (new_ndlp) | ||
4123 | mempool_free(ndlp, phba->nlp_mem_pool); | ||
4124 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 4330 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
4125 | 4331 | ||
4126 | lpfc_printf_log(phba, KERN_ERR, LOG_ELS, | 4332 | lpfc_printf_log(phba, KERN_ERR, LOG_ELS, |
@@ -4163,11 +4369,13 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, | |||
4163 | phba->fc_stat.elsXmitFDISC++; | 4369 | phba->fc_stat.elsXmitFDISC++; |
4164 | elsiocb->iocb_cmpl = lpfc_cmpl_els_fdisc; | 4370 | elsiocb->iocb_cmpl = lpfc_cmpl_els_fdisc; |
4165 | 4371 | ||
4372 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, | ||
4373 | "Issue FDISC: did:x%x", | ||
4374 | did, 0, 0); | ||
4375 | |||
4166 | rc = lpfc_issue_fabric_iocb(phba, elsiocb); | 4376 | rc = lpfc_issue_fabric_iocb(phba, elsiocb); |
4167 | if (rc == IOCB_ERROR) { | 4377 | if (rc == IOCB_ERROR) { |
4168 | lpfc_els_free_iocb(phba, elsiocb); | 4378 | lpfc_els_free_iocb(phba, elsiocb); |
4169 | if (new_ndlp) | ||
4170 | mempool_free(ndlp, phba->nlp_mem_pool); | ||
4171 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); | 4379 | lpfc_vport_set_state(vport, FC_VPORT_FAILED); |
4172 | 4380 | ||
4173 | lpfc_printf_log(phba, KERN_ERR, LOG_ELS, | 4381 | lpfc_printf_log(phba, KERN_ERR, LOG_ELS, |
@@ -4186,6 +4394,12 @@ lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
4186 | struct lpfc_iocbq *rspiocb) | 4394 | struct lpfc_iocbq *rspiocb) |
4187 | { | 4395 | { |
4188 | struct lpfc_vport *vport = cmdiocb->vport; | 4396 | struct lpfc_vport *vport = cmdiocb->vport; |
4397 | IOCB_t *irsp; | ||
4398 | |||
4399 | irsp = &rspiocb->iocb; | ||
4400 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, | ||
4401 | "LOGO npiv cmpl: status:x%x/x%x did:x%x", | ||
4402 | irsp->ulpStatus, irsp->un.ulpWord[4], irsp->un.rcvels.remoteID); | ||
4189 | 4403 | ||
4190 | lpfc_els_free_iocb(phba, cmdiocb); | 4404 | lpfc_els_free_iocb(phba, cmdiocb); |
4191 | vport->unreg_vpi_cmpl = VPORT_ERROR; | 4405 | vport->unreg_vpi_cmpl = VPORT_ERROR; |
@@ -4218,6 +4432,10 @@ lpfc_issue_els_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) | |||
4218 | pcmd += sizeof(uint32_t); | 4432 | pcmd += sizeof(uint32_t); |
4219 | memcpy(pcmd, &vport->fc_portname, sizeof(struct lpfc_name)); | 4433 | memcpy(pcmd, &vport->fc_portname, sizeof(struct lpfc_name)); |
4220 | 4434 | ||
4435 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD, | ||
4436 | "Issue LOGO npiv did:x%x flg:x%x", | ||
4437 | ndlp->nlp_DID, ndlp->nlp_flag, 0); | ||
4438 | |||
4221 | elsiocb->iocb_cmpl = lpfc_cmpl_els_npiv_logo; | 4439 | elsiocb->iocb_cmpl = lpfc_cmpl_els_npiv_logo; |
4222 | spin_lock_irq(shost->host_lock); | 4440 | spin_lock_irq(shost->host_lock); |
4223 | ndlp->nlp_flag |= NLP_LOGO_SND; | 4441 | ndlp->nlp_flag |= NLP_LOGO_SND; |
@@ -4277,6 +4495,10 @@ repeat: | |||
4277 | iocb->iocb_cmpl = lpfc_cmpl_fabric_iocb; | 4495 | iocb->iocb_cmpl = lpfc_cmpl_fabric_iocb; |
4278 | iocb->iocb_flag |= LPFC_IO_FABRIC; | 4496 | iocb->iocb_flag |= LPFC_IO_FABRIC; |
4279 | 4497 | ||
4498 | lpfc_debugfs_disc_trc(iocb->vport, LPFC_DISC_TRC_ELS_CMD, | ||
4499 | "Fabric sched1: ste:x%x", | ||
4500 | iocb->vport->port_state, 0, 0); | ||
4501 | |||
4280 | ret = lpfc_sli_issue_iocb(phba, pring, iocb, 0); | 4502 | ret = lpfc_sli_issue_iocb(phba, pring, iocb, 0); |
4281 | 4503 | ||
4282 | if (ret == IOCB_ERROR) { | 4504 | if (ret == IOCB_ERROR) { |
@@ -4387,6 +4609,10 @@ lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb) | |||
4387 | iocb->iocb_cmpl = lpfc_cmpl_fabric_iocb; | 4609 | iocb->iocb_cmpl = lpfc_cmpl_fabric_iocb; |
4388 | iocb->iocb_flag |= LPFC_IO_FABRIC; | 4610 | iocb->iocb_flag |= LPFC_IO_FABRIC; |
4389 | 4611 | ||
4612 | lpfc_debugfs_disc_trc(iocb->vport, LPFC_DISC_TRC_ELS_CMD, | ||
4613 | "Fabric sched2: ste:x%x", | ||
4614 | iocb->vport->port_state, 0, 0); | ||
4615 | |||
4390 | atomic_inc(&phba->fabric_iocb_count); | 4616 | atomic_inc(&phba->fabric_iocb_count); |
4391 | ret = lpfc_sli_issue_iocb(phba, pring, iocb, 0); | 4617 | ret = lpfc_sli_issue_iocb(phba, pring, iocb, 0); |
4392 | 4618 | ||