Commit 82d9a2a2 authored by James Smart's avatar James Smart Committed by James Bottomley

[SCSI] lpfc 8.1.5 : Fixed FC protocol violation in handling of PRLO.

Fixed FC protocol violation in handling of PRLO.
Signed-off-by: default avatarJames Smart <James.Smart@emulex.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 4b0b91d4
...@@ -1913,6 +1913,7 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, ...@@ -1913,6 +1913,7 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag,
uint8_t *pcmd; uint8_t *pcmd;
uint16_t cmdsize; uint16_t cmdsize;
int rc; int rc;
ELS_PKT *els_pkt_ptr;
psli = &phba->sli; psli = &phba->sli;
pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */ pring = &psli->ring[LPFC_ELS_RING]; /* ELS ring */
...@@ -1951,6 +1952,23 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag, ...@@ -1951,6 +1952,23 @@ lpfc_els_rsp_acc(struct lpfc_hba * phba, uint32_t flag,
pcmd += sizeof (uint32_t); pcmd += sizeof (uint32_t);
memcpy(pcmd, &phba->fc_sparam, sizeof (struct serv_parm)); memcpy(pcmd, &phba->fc_sparam, sizeof (struct serv_parm));
break; break;
case ELS_CMD_PRLO:
cmdsize = sizeof (uint32_t) + sizeof (PRLO);
elsiocb = lpfc_prep_els_iocb(phba, 0, cmdsize, oldiocb->retry,
ndlp, ndlp->nlp_DID, ELS_CMD_PRLO);
if (!elsiocb)
return 1;
icmd = &elsiocb->iocb;
icmd->ulpContext = oldcmd->ulpContext; /* Xri */
pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
memcpy(pcmd, ((struct lpfc_dmabuf *) oldiocb->context2)->virt,
sizeof (uint32_t) + sizeof (PRLO));
*((uint32_t *) (pcmd)) = ELS_CMD_PRLO_ACC;
els_pkt_ptr = (ELS_PKT *) pcmd;
els_pkt_ptr->un.prlo.acceptRspCode = PRLO_REQ_EXECUTED;
break;
default: default:
return 1; return 1;
} }
......
...@@ -449,6 +449,7 @@ struct serv_parm { /* Structure is in Big Endian format */ ...@@ -449,6 +449,7 @@ struct serv_parm { /* Structure is in Big Endian format */
#define ELS_CMD_RRQ 0x12000000 #define ELS_CMD_RRQ 0x12000000
#define ELS_CMD_PRLI 0x20100014 #define ELS_CMD_PRLI 0x20100014
#define ELS_CMD_PRLO 0x21100014 #define ELS_CMD_PRLO 0x21100014
#define ELS_CMD_PRLO_ACC 0x02100014
#define ELS_CMD_PDISC 0x50000000 #define ELS_CMD_PDISC 0x50000000
#define ELS_CMD_FDISC 0x51000000 #define ELS_CMD_FDISC 0x51000000
#define ELS_CMD_ADISC 0x52000000 #define ELS_CMD_ADISC 0x52000000
...@@ -484,6 +485,7 @@ struct serv_parm { /* Structure is in Big Endian format */ ...@@ -484,6 +485,7 @@ struct serv_parm { /* Structure is in Big Endian format */
#define ELS_CMD_RRQ 0x12 #define ELS_CMD_RRQ 0x12
#define ELS_CMD_PRLI 0x14001020 #define ELS_CMD_PRLI 0x14001020
#define ELS_CMD_PRLO 0x14001021 #define ELS_CMD_PRLO 0x14001021
#define ELS_CMD_PRLO_ACC 0x14001002
#define ELS_CMD_PDISC 0x50 #define ELS_CMD_PDISC 0x50
#define ELS_CMD_FDISC 0x51 #define ELS_CMD_FDISC 0x51
#define ELS_CMD_ADISC 0x52 #define ELS_CMD_ADISC 0x52
......
...@@ -465,13 +465,17 @@ lpfc_rcv_padisc(struct lpfc_hba * phba, ...@@ -465,13 +465,17 @@ lpfc_rcv_padisc(struct lpfc_hba * phba,
static int static int
lpfc_rcv_logo(struct lpfc_hba * phba, lpfc_rcv_logo(struct lpfc_hba * phba,
struct lpfc_nodelist * ndlp, struct lpfc_nodelist * ndlp,
struct lpfc_iocbq *cmdiocb) struct lpfc_iocbq *cmdiocb,
uint32_t els_cmd)
{ {
/* Put ndlp on NPR list with 1 sec timeout for plogi, ACC logo */ /* Put ndlp on NPR list with 1 sec timeout for plogi, ACC logo */
/* Only call LOGO ACC for first LOGO, this avoids sending unnecessary /* Only call LOGO ACC for first LOGO, this avoids sending unnecessary
* PLOGIs during LOGO storms from a device. * PLOGIs during LOGO storms from a device.
*/ */
ndlp->nlp_flag |= NLP_LOGO_ACC; ndlp->nlp_flag |= NLP_LOGO_ACC;
if (els_cmd == ELS_CMD_PRLO)
lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
else
lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0);
if (!(ndlp->nlp_type & NLP_FABRIC) || if (!(ndlp->nlp_type & NLP_FABRIC) ||
...@@ -681,7 +685,7 @@ lpfc_rcv_logo_plogi_issue(struct lpfc_hba * phba, ...@@ -681,7 +685,7 @@ lpfc_rcv_logo_plogi_issue(struct lpfc_hba * phba,
/* software abort outstanding PLOGI */ /* software abort outstanding PLOGI */
lpfc_els_abort(phba, ndlp, 1); lpfc_els_abort(phba, ndlp, 1);
lpfc_rcv_logo(phba, ndlp, cmdiocb); lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);
return ndlp->nlp_state; return ndlp->nlp_state;
} }
...@@ -907,7 +911,7 @@ lpfc_rcv_logo_adisc_issue(struct lpfc_hba * phba, ...@@ -907,7 +911,7 @@ lpfc_rcv_logo_adisc_issue(struct lpfc_hba * phba,
/* software abort outstanding ADISC */ /* software abort outstanding ADISC */
lpfc_els_abort(phba, ndlp, 0); lpfc_els_abort(phba, ndlp, 0);
lpfc_rcv_logo(phba, ndlp, cmdiocb); lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);
return ndlp->nlp_state; return ndlp->nlp_state;
} }
...@@ -934,7 +938,7 @@ lpfc_rcv_prlo_adisc_issue(struct lpfc_hba * phba, ...@@ -934,7 +938,7 @@ lpfc_rcv_prlo_adisc_issue(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
/* Treat like rcv logo */ /* Treat like rcv logo */
lpfc_rcv_logo(phba, ndlp, cmdiocb); lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_PRLO);
return ndlp->nlp_state; return ndlp->nlp_state;
} }
...@@ -1056,7 +1060,7 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba, ...@@ -1056,7 +1060,7 @@ lpfc_rcv_logo_reglogin_issue(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_rcv_logo(phba, ndlp, cmdiocb); lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);
return ndlp->nlp_state; return ndlp->nlp_state;
} }
...@@ -1081,7 +1085,7 @@ lpfc_rcv_prlo_reglogin_issue(struct lpfc_hba * phba, ...@@ -1081,7 +1085,7 @@ lpfc_rcv_prlo_reglogin_issue(struct lpfc_hba * phba,
struct lpfc_iocbq *cmdiocb; struct lpfc_iocbq *cmdiocb;
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
return ndlp->nlp_state; return ndlp->nlp_state;
} }
...@@ -1200,7 +1204,7 @@ lpfc_rcv_logo_prli_issue(struct lpfc_hba * phba, ...@@ -1200,7 +1204,7 @@ lpfc_rcv_logo_prli_issue(struct lpfc_hba * phba,
/* Software abort outstanding PRLI before sending acc */ /* Software abort outstanding PRLI before sending acc */
lpfc_els_abort(phba, ndlp, 1); lpfc_els_abort(phba, ndlp, 1);
lpfc_rcv_logo(phba, ndlp, cmdiocb); lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);
return ndlp->nlp_state; return ndlp->nlp_state;
} }
...@@ -1228,7 +1232,7 @@ lpfc_rcv_prlo_prli_issue(struct lpfc_hba * phba, ...@@ -1228,7 +1232,7 @@ lpfc_rcv_prlo_prli_issue(struct lpfc_hba * phba,
struct lpfc_iocbq *cmdiocb; struct lpfc_iocbq *cmdiocb;
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
return ndlp->nlp_state; return ndlp->nlp_state;
} }
...@@ -1371,7 +1375,7 @@ lpfc_rcv_logo_unmap_node(struct lpfc_hba * phba, ...@@ -1371,7 +1375,7 @@ lpfc_rcv_logo_unmap_node(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_rcv_logo(phba, ndlp, cmdiocb); lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);
return ndlp->nlp_state; return ndlp->nlp_state;
} }
...@@ -1395,7 +1399,7 @@ lpfc_rcv_prlo_unmap_node(struct lpfc_hba * phba, ...@@ -1395,7 +1399,7 @@ lpfc_rcv_prlo_unmap_node(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_els_rsp_acc(phba, ELS_CMD_ACC, cmdiocb, ndlp, NULL, 0); lpfc_els_rsp_acc(phba, ELS_CMD_PRLO, cmdiocb, ndlp, NULL, 0);
return ndlp->nlp_state; return ndlp->nlp_state;
} }
...@@ -1444,7 +1448,7 @@ lpfc_rcv_logo_mapped_node(struct lpfc_hba * phba, ...@@ -1444,7 +1448,7 @@ lpfc_rcv_logo_mapped_node(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_rcv_logo(phba, ndlp, cmdiocb); lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);
return ndlp->nlp_state; return ndlp->nlp_state;
} }
...@@ -1476,7 +1480,7 @@ lpfc_rcv_prlo_mapped_node(struct lpfc_hba * phba, ...@@ -1476,7 +1480,7 @@ lpfc_rcv_prlo_mapped_node(struct lpfc_hba * phba,
spin_unlock_irq(phba->host->host_lock); spin_unlock_irq(phba->host->host_lock);
/* Treat like rcv logo */ /* Treat like rcv logo */
lpfc_rcv_logo(phba, ndlp, cmdiocb); lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_PRLO);
return ndlp->nlp_state; return ndlp->nlp_state;
} }
...@@ -1571,7 +1575,7 @@ lpfc_rcv_logo_npr_node(struct lpfc_hba * phba, ...@@ -1571,7 +1575,7 @@ lpfc_rcv_logo_npr_node(struct lpfc_hba * phba,
cmdiocb = (struct lpfc_iocbq *) arg; cmdiocb = (struct lpfc_iocbq *) arg;
lpfc_rcv_logo(phba, ndlp, cmdiocb); lpfc_rcv_logo(phba, ndlp, cmdiocb, ELS_CMD_LOGO);
return ndlp->nlp_state; return ndlp->nlp_state;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment