[SCSI] lpfc 8.3.29: SLI related fixes
SLI related fixes: - Fix REG_RPI fails on SLI4 HBA putting NPort into NPR state (126230) - Fix ELS FDISC failing with local reject / invalid RPI. (126350) - Fix reset port when reset is needed during fw_dump (125807) - Fix unbounded firmware revision string from port cause panic (126560) - Fix driver behavior when receiving an ADISC (126654) - Fix driver not returning when bad ndlp found in abts error event handling (126209) - Add more driver logs in area of SLI4 port error attention and reset recovery (126813, 124466) - Fix failure in handling large CQ/EQ identifiers in an IOV environment (126856) - Fix for driver using duplicate RPIs after lancer port reset (126723) - Clear vport->fc_myDID in lpfc_els_issue_fdisc to guarentee a zero SID (126779, 126897) - Fix for SLI4 Port delivery for BLS ABORT ACC (126289) Signed-off-by: Alex Iannicelli <alex.iannicelli@emulex.com> Signed-off-by: James Smart <james.smart@emulex.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
此提交包含在:
@@ -48,6 +48,10 @@ static int
|
||||
lpfc_check_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
struct lpfc_name *nn, struct lpfc_name *pn)
|
||||
{
|
||||
/* First, we MUST have a RPI registered */
|
||||
if (!(ndlp->nlp_flag & NLP_RPI_REGISTERED))
|
||||
return 0;
|
||||
|
||||
/* Compare the ADISC rsp WWNN / WWPN matches our internal node
|
||||
* table entry for that node.
|
||||
*/
|
||||
@@ -385,6 +389,10 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
if (!mbox)
|
||||
goto out;
|
||||
|
||||
/* Registering an existing RPI behaves differently for SLI3 vs SLI4 */
|
||||
if (phba->sli_rev == LPFC_SLI_REV4)
|
||||
lpfc_unreg_rpi(vport, ndlp);
|
||||
|
||||
rc = lpfc_reg_rpi(phba, vport->vpi, icmd->un.rcvels.remoteID,
|
||||
(uint8_t *) sp, mbox, ndlp->nlp_rpi);
|
||||
if (rc) {
|
||||
@@ -445,11 +453,42 @@ out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* lpfc_mbx_cmpl_resume_rpi - Resume RPI completion routine
|
||||
* @phba: pointer to lpfc hba data structure.
|
||||
* @mboxq: pointer to mailbox object
|
||||
*
|
||||
* This routine is invoked to issue a completion to a rcv'ed
|
||||
* ADISC or PDISC after the paused RPI has been resumed.
|
||||
**/
|
||||
static void
|
||||
lpfc_mbx_cmpl_resume_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
|
||||
{
|
||||
struct lpfc_vport *vport;
|
||||
struct lpfc_iocbq *elsiocb;
|
||||
struct lpfc_nodelist *ndlp;
|
||||
uint32_t cmd;
|
||||
|
||||
elsiocb = (struct lpfc_iocbq *)mboxq->context1;
|
||||
ndlp = (struct lpfc_nodelist *) mboxq->context2;
|
||||
vport = mboxq->vport;
|
||||
cmd = elsiocb->drvrTimeout;
|
||||
|
||||
if (cmd == ELS_CMD_ADISC) {
|
||||
lpfc_els_rsp_adisc_acc(vport, elsiocb, ndlp);
|
||||
} else {
|
||||
lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, elsiocb,
|
||||
ndlp, NULL);
|
||||
}
|
||||
kfree(elsiocb);
|
||||
}
|
||||
|
||||
static int
|
||||
lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
struct lpfc_iocbq *cmdiocb)
|
||||
{
|
||||
struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
|
||||
struct lpfc_iocbq *elsiocb;
|
||||
struct lpfc_dmabuf *pcmd;
|
||||
struct serv_parm *sp;
|
||||
struct lpfc_name *pnn, *ppn;
|
||||
@@ -475,12 +514,43 @@ lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
|
||||
|
||||
icmd = &cmdiocb->iocb;
|
||||
if (icmd->ulpStatus == 0 && lpfc_check_adisc(vport, ndlp, pnn, ppn)) {
|
||||
|
||||
/*
|
||||
* As soon as we send ACC, the remote NPort can
|
||||
* start sending us data. Thus, for SLI4 we must
|
||||
* resume the RPI before the ACC goes out.
|
||||
*/
|
||||
if (vport->phba->sli_rev == LPFC_SLI_REV4) {
|
||||
elsiocb = kmalloc(sizeof(struct lpfc_iocbq),
|
||||
GFP_KERNEL);
|
||||
if (elsiocb) {
|
||||
|
||||
/* Save info from cmd IOCB used in rsp */
|
||||
memcpy((uint8_t *)elsiocb, (uint8_t *)cmdiocb,
|
||||
sizeof(struct lpfc_iocbq));
|
||||
|
||||
/* Save the ELS cmd */
|
||||
elsiocb->drvrTimeout = cmd;
|
||||
|
||||
lpfc_sli4_resume_rpi(ndlp,
|
||||
lpfc_mbx_cmpl_resume_rpi, elsiocb);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (cmd == ELS_CMD_ADISC) {
|
||||
lpfc_els_rsp_adisc_acc(vport, cmdiocb, ndlp);
|
||||
} else {
|
||||
lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp,
|
||||
NULL);
|
||||
lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb,
|
||||
ndlp, NULL);
|
||||
}
|
||||
out:
|
||||
/* If we are authenticated, move to the proper state */
|
||||
if (ndlp->nlp_type & NLP_FCP_TARGET)
|
||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE);
|
||||
else
|
||||
lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/* Reject this request because invalid parameters */
|
||||
@@ -1229,7 +1299,7 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_vport *vport,
|
||||
}
|
||||
|
||||
if (phba->sli_rev == LPFC_SLI_REV4) {
|
||||
rc = lpfc_sli4_resume_rpi(ndlp);
|
||||
rc = lpfc_sli4_resume_rpi(ndlp, NULL, NULL);
|
||||
if (rc) {
|
||||
/* Stay in state and retry. */
|
||||
ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
|
||||
|
新增問題並參考
封鎖使用者