diff options
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_els.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_els.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index b9440deaad45..08d156a9094f 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c | |||
@@ -3122,6 +3122,13 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, | |||
3122 | 3122 | ||
3123 | case IOERR_SEQUENCE_TIMEOUT: | 3123 | case IOERR_SEQUENCE_TIMEOUT: |
3124 | case IOERR_INVALID_RPI: | 3124 | case IOERR_INVALID_RPI: |
3125 | if (cmd == ELS_CMD_PLOGI && | ||
3126 | did == NameServer_DID) { | ||
3127 | /* Continue forever if plogi to */ | ||
3128 | /* the nameserver fails */ | ||
3129 | maxretry = 0; | ||
3130 | delay = 100; | ||
3131 | } | ||
3125 | retry = 1; | 3132 | retry = 1; |
3126 | break; | 3133 | break; |
3127 | } | 3134 | } |
@@ -6517,7 +6524,8 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
6517 | struct lpfc_nodelist *ndlp; | 6524 | struct lpfc_nodelist *ndlp; |
6518 | struct ls_rjt stat; | 6525 | struct ls_rjt stat; |
6519 | uint32_t *payload; | 6526 | uint32_t *payload; |
6520 | uint32_t cmd, did, newnode, rjt_err = 0; | 6527 | uint32_t cmd, did, newnode; |
6528 | uint8_t rjt_exp, rjt_err = 0; | ||
6521 | IOCB_t *icmd = &elsiocb->iocb; | 6529 | IOCB_t *icmd = &elsiocb->iocb; |
6522 | 6530 | ||
6523 | if (!vport || !(elsiocb->context2)) | 6531 | if (!vport || !(elsiocb->context2)) |
@@ -6606,12 +6614,14 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
6606 | /* If Nport discovery is delayed, reject PLOGIs */ | 6614 | /* If Nport discovery is delayed, reject PLOGIs */ |
6607 | if (vport->fc_flag & FC_DISC_DELAYED) { | 6615 | if (vport->fc_flag & FC_DISC_DELAYED) { |
6608 | rjt_err = LSRJT_UNABLE_TPC; | 6616 | rjt_err = LSRJT_UNABLE_TPC; |
6617 | rjt_exp = LSEXP_NOTHING_MORE; | ||
6609 | break; | 6618 | break; |
6610 | } | 6619 | } |
6611 | if (vport->port_state < LPFC_DISC_AUTH) { | 6620 | if (vport->port_state < LPFC_DISC_AUTH) { |
6612 | if (!(phba->pport->fc_flag & FC_PT2PT) || | 6621 | if (!(phba->pport->fc_flag & FC_PT2PT) || |
6613 | (phba->pport->fc_flag & FC_PT2PT_PLOGI)) { | 6622 | (phba->pport->fc_flag & FC_PT2PT_PLOGI)) { |
6614 | rjt_err = LSRJT_UNABLE_TPC; | 6623 | rjt_err = LSRJT_UNABLE_TPC; |
6624 | rjt_exp = LSEXP_NOTHING_MORE; | ||
6615 | break; | 6625 | break; |
6616 | } | 6626 | } |
6617 | /* We get here, and drop thru, if we are PT2PT with | 6627 | /* We get here, and drop thru, if we are PT2PT with |
@@ -6648,6 +6658,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
6648 | lpfc_send_els_event(vport, ndlp, payload); | 6658 | lpfc_send_els_event(vport, ndlp, payload); |
6649 | if (vport->port_state < LPFC_DISC_AUTH) { | 6659 | if (vport->port_state < LPFC_DISC_AUTH) { |
6650 | rjt_err = LSRJT_UNABLE_TPC; | 6660 | rjt_err = LSRJT_UNABLE_TPC; |
6661 | rjt_exp = LSEXP_NOTHING_MORE; | ||
6651 | break; | 6662 | break; |
6652 | } | 6663 | } |
6653 | lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_LOGO); | 6664 | lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_LOGO); |
@@ -6661,6 +6672,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
6661 | lpfc_send_els_event(vport, ndlp, payload); | 6672 | lpfc_send_els_event(vport, ndlp, payload); |
6662 | if (vport->port_state < LPFC_DISC_AUTH) { | 6673 | if (vport->port_state < LPFC_DISC_AUTH) { |
6663 | rjt_err = LSRJT_UNABLE_TPC; | 6674 | rjt_err = LSRJT_UNABLE_TPC; |
6675 | rjt_exp = LSEXP_NOTHING_MORE; | ||
6664 | break; | 6676 | break; |
6665 | } | 6677 | } |
6666 | lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLO); | 6678 | lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLO); |
@@ -6680,6 +6692,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
6680 | phba->fc_stat.elsRcvADISC++; | 6692 | phba->fc_stat.elsRcvADISC++; |
6681 | if (vport->port_state < LPFC_DISC_AUTH) { | 6693 | if (vport->port_state < LPFC_DISC_AUTH) { |
6682 | rjt_err = LSRJT_UNABLE_TPC; | 6694 | rjt_err = LSRJT_UNABLE_TPC; |
6695 | rjt_exp = LSEXP_NOTHING_MORE; | ||
6683 | break; | 6696 | break; |
6684 | } | 6697 | } |
6685 | lpfc_disc_state_machine(vport, ndlp, elsiocb, | 6698 | lpfc_disc_state_machine(vport, ndlp, elsiocb, |
@@ -6693,6 +6706,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
6693 | phba->fc_stat.elsRcvPDISC++; | 6706 | phba->fc_stat.elsRcvPDISC++; |
6694 | if (vport->port_state < LPFC_DISC_AUTH) { | 6707 | if (vport->port_state < LPFC_DISC_AUTH) { |
6695 | rjt_err = LSRJT_UNABLE_TPC; | 6708 | rjt_err = LSRJT_UNABLE_TPC; |
6709 | rjt_exp = LSEXP_NOTHING_MORE; | ||
6696 | break; | 6710 | break; |
6697 | } | 6711 | } |
6698 | lpfc_disc_state_machine(vport, ndlp, elsiocb, | 6712 | lpfc_disc_state_machine(vport, ndlp, elsiocb, |
@@ -6730,6 +6744,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
6730 | phba->fc_stat.elsRcvPRLI++; | 6744 | phba->fc_stat.elsRcvPRLI++; |
6731 | if (vport->port_state < LPFC_DISC_AUTH) { | 6745 | if (vport->port_state < LPFC_DISC_AUTH) { |
6732 | rjt_err = LSRJT_UNABLE_TPC; | 6746 | rjt_err = LSRJT_UNABLE_TPC; |
6747 | rjt_exp = LSEXP_NOTHING_MORE; | ||
6733 | break; | 6748 | break; |
6734 | } | 6749 | } |
6735 | lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLI); | 6750 | lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLI); |
@@ -6813,6 +6828,11 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
6813 | if (newnode) | 6828 | if (newnode) |
6814 | lpfc_nlp_put(ndlp); | 6829 | lpfc_nlp_put(ndlp); |
6815 | break; | 6830 | break; |
6831 | case ELS_CMD_REC: | ||
6832 | /* receive this due to exchange closed */ | ||
6833 | rjt_err = LSRJT_UNABLE_TPC; | ||
6834 | rjt_exp = LSEXP_INVALID_OX_RX; | ||
6835 | break; | ||
6816 | default: | 6836 | default: |
6817 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, | 6837 | lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL, |
6818 | "RCV ELS cmd: cmd:x%x did:x%x/ste:x%x", | 6838 | "RCV ELS cmd: cmd:x%x did:x%x/ste:x%x", |
@@ -6820,6 +6840,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
6820 | 6840 | ||
6821 | /* Unsupported ELS command, reject */ | 6841 | /* Unsupported ELS command, reject */ |
6822 | rjt_err = LSRJT_CMD_UNSUPPORTED; | 6842 | rjt_err = LSRJT_CMD_UNSUPPORTED; |
6843 | rjt_exp = LSEXP_NOTHING_MORE; | ||
6823 | 6844 | ||
6824 | /* Unknown ELS command <elsCmd> received from NPORT <did> */ | 6845 | /* Unknown ELS command <elsCmd> received from NPORT <did> */ |
6825 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, | 6846 | lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS, |
@@ -6834,7 +6855,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, | |||
6834 | if (rjt_err) { | 6855 | if (rjt_err) { |
6835 | memset(&stat, 0, sizeof(stat)); | 6856 | memset(&stat, 0, sizeof(stat)); |
6836 | stat.un.b.lsRjtRsnCode = rjt_err; | 6857 | stat.un.b.lsRjtRsnCode = rjt_err; |
6837 | stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE; | 6858 | stat.un.b.lsRjtRsnCodeExp = rjt_exp; |
6838 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, elsiocb, ndlp, | 6859 | lpfc_els_rsp_reject(vport, stat.un.lsRjtError, elsiocb, ndlp, |
6839 | NULL); | 6860 | NULL); |
6840 | } | 6861 | } |