diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-03-24 19:37:53 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-03-24 19:37:53 -0700 |
commit | 6f2689a7662809ff39f2b24e452d11569c21ea2f (patch) | |
tree | 6dfbfd3feb4d77a66bf06f246640ae4ed321bbb2 /drivers/scsi/lpfc/lpfc_nportdisc.c | |
parent | b1f8ccdaae0310332d16f65bf0f622f9d4ae2391 (diff) | |
parent | 66daf3e6b9936328cb28eaaa29dddfe96343cc85 (diff) |
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull SCSI updates from James Bottomley:
"This series consists of the usual driver updates (qla2xxx, pm8001,
libsas, smartpqi, scsi_debug, lpfc, iscsi, mpi3mr) plus minor updates
and bug fixes.
The high blast radius core update is the removal of write same, which
affects block and several non-SCSI devices. The other big change,
which is more local, is the removal of the SCSI pointer"
* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (281 commits)
scsi: scsi_ioctl: Drop needless assignment in sg_io()
scsi: bsg: Drop needless assignment in scsi_bsg_sg_io_fn()
scsi: lpfc: Copyright updates for 14.2.0.0 patches
scsi: lpfc: Update lpfc version to 14.2.0.0
scsi: lpfc: SLI path split: Refactor BSG paths
scsi: lpfc: SLI path split: Refactor Abort paths
scsi: lpfc: SLI path split: Refactor SCSI paths
scsi: lpfc: SLI path split: Refactor CT paths
scsi: lpfc: SLI path split: Refactor misc ELS paths
scsi: lpfc: SLI path split: Refactor VMID paths
scsi: lpfc: SLI path split: Refactor FDISC paths
scsi: lpfc: SLI path split: Refactor LS_RJT paths
scsi: lpfc: SLI path split: Refactor LS_ACC paths
scsi: lpfc: SLI path split: Refactor the RSCN/SCR/RDF/EDC/FARPR paths
scsi: lpfc: SLI path split: Refactor PLOGI/PRLI/ADISC/LOGO paths
scsi: lpfc: SLI path split: Refactor base ELS paths and the FLOGI path
scsi: lpfc: SLI path split: Introduce lpfc_prep_wqe
scsi: lpfc: SLI path split: Refactor fast and slow paths to native SLI4
scsi: lpfc: SLI path split: Refactor lpfc_iocbq
scsi: lpfc: Use kcalloc()
...
Diffstat (limited to 'drivers/scsi/lpfc/lpfc_nportdisc.c')
-rw-r--r-- | drivers/scsi/lpfc/lpfc_nportdisc.c | 104 |
1 files changed, 67 insertions, 37 deletions
diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index fdf5e777bf11..c4e1a07066a2 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -1,7 +1,7 @@ /******************************************************************* * This file is part of the Emulex Linux Device Driver for * * Fibre Channel Host Bus Adapters. * - * Copyright (C) 2017-2021 Broadcom. All Rights Reserved. The term * + * Copyright (C) 2017-2022 Broadcom. All Rights Reserved. The term * * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. * * Copyright (C) 2004-2016 Emulex. All rights reserved. * * EMULEX and SLI are trademarks of Emulex. * @@ -171,9 +171,8 @@ lpfc_check_elscmpl_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct lpfc_dmabuf *pcmd, *prsp; uint32_t *lp; void *ptr = NULL; - IOCB_t *irsp; + u32 ulp_status = get_job_ulpstatus(phba, rspiocb); - irsp = &rspiocb->iocb; pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; /* For lpfc_els_abort, context2 could be zero'ed to delay @@ -187,10 +186,16 @@ lpfc_check_elscmpl_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ptr = (void *)((uint8_t *)lp + sizeof(uint32_t)); } } else { - /* Force ulpStatus error since we are returning NULL ptr */ - if (!(irsp->ulpStatus)) { - irsp->ulpStatus = IOSTAT_LOCAL_REJECT; - irsp->un.ulpWord[4] = IOERR_SLI_ABORTED; + /* Force ulp_status error since we are returning NULL ptr */ + if (!(ulp_status)) { + if (phba->sli_rev == LPFC_SLI_REV4) { + bf_set(lpfc_wcqe_c_status, &rspiocb->wcqe_cmpl, + IOSTAT_LOCAL_REJECT); + rspiocb->wcqe_cmpl.parameter = IOERR_SLI_ABORTED; + } else { + rspiocb->iocb.ulpStatus = IOSTAT_LOCAL_REJECT; + rspiocb->iocb.un.ulpWord[4] = IOERR_SLI_ABORTED; + } } ptr = NULL; } @@ -325,6 +330,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, struct lpfc_dmabuf *mp; uint64_t nlp_portwwn = 0; uint32_t *lp; + union lpfc_wqe128 *wqe; IOCB_t *icmd; struct serv_parm *sp; uint32_t ed_tov; @@ -334,6 +340,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, struct ls_rjt stat; uint32_t vid, flag; int rc; + u32 remote_did; memset(&stat, 0, sizeof (struct ls_rjt)); pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; @@ -367,7 +374,11 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, NULL); return 0; } - icmd = &cmdiocb->iocb; + + if (phba->sli_rev == LPFC_SLI_REV4) + wqe = &cmdiocb->wqe; + else + icmd = &cmdiocb->iocb; /* PLOGI chkparm OK */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, @@ -457,7 +468,12 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, if ((vport->fc_flag & FC_PT2PT) && !(vport->fc_flag & FC_PT2PT_PLOGI)) { /* rcv'ed PLOGI decides what our NPortId will be */ - vport->fc_myDID = icmd->un.rcvels.parmRo; + if (phba->sli_rev == LPFC_SLI_REV4) { + vport->fc_myDID = bf_get(els_rsp64_sid, + &cmdiocb->wqe.xmit_els_rsp); + } else { + vport->fc_myDID = icmd->un.rcvels.parmRo; + } /* If there is an outstanding FLOGI, abort it now. * The remote NPort is not going to ACC our FLOGI @@ -538,7 +554,11 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, /* Issue REG_LOGIN first, before ACCing the PLOGI, thus we will * always be deferring the ACC. */ - rc = lpfc_reg_rpi(phba, vport->vpi, icmd->un.rcvels.remoteID, + if (phba->sli_rev == LPFC_SLI_REV4) + remote_did = bf_get(wqe_els_did, &wqe->xmit_els_rsp.wqe_dest); + else + remote_did = icmd->un.rcvels.remoteID; + rc = lpfc_reg_rpi(phba, vport->vpi, remote_did, (uint8_t *)sp, login_mbox, ndlp->nlp_rpi); if (rc) goto out; @@ -680,13 +700,13 @@ static int lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, struct lpfc_iocbq *cmdiocb) { + struct lpfc_hba *phba = vport->phba; struct lpfc_iocbq *elsiocb; struct lpfc_dmabuf *pcmd; struct serv_parm *sp; struct lpfc_name *pnn, *ppn; struct ls_rjt stat; ADISC *ap; - IOCB_t *icmd; uint32_t *lp; uint32_t cmd; @@ -704,8 +724,8 @@ lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, ppn = (struct lpfc_name *) & sp->portName; } - icmd = &cmdiocb->iocb; - if (icmd->ulpStatus == 0 && lpfc_check_adisc(vport, ndlp, pnn, ppn)) { + if (get_job_ulpstatus(phba, cmdiocb) == 0 && + lpfc_check_adisc(vport, ndlp, pnn, ppn)) { /* * As soon as we send ACC, the remote NPort can @@ -716,7 +736,6 @@ lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, 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)); @@ -1312,23 +1331,24 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, struct lpfc_dmabuf *pcmd, *prsp, *mp; uint32_t *lp; uint32_t vid, flag; - IOCB_t *irsp; struct serv_parm *sp; uint32_t ed_tov; LPFC_MBOXQ_t *mbox; int rc; + u32 ulp_status; + u32 did; cmdiocb = (struct lpfc_iocbq *) arg; rspiocb = cmdiocb->context_un.rsp_iocb; + ulp_status = get_job_ulpstatus(phba, rspiocb); + if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) { /* Recovery from PLOGI collision logic */ return ndlp->nlp_state; } - irsp = &rspiocb->iocb; - - if (irsp->ulpStatus) + if (ulp_status) goto out; pcmd = (struct lpfc_dmabuf *) cmdiocb->context2; @@ -1440,7 +1460,9 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport, goto out; } - if (lpfc_reg_rpi(phba, vport->vpi, irsp->un.elsreq64.remoteID, + did = get_job_els_rsp64_did(phba, cmdiocb); + + if (lpfc_reg_rpi(phba, vport->vpi, did, (uint8_t *) sp, mbox, ndlp->nlp_rpi) == 0) { switch (ndlp->nlp_DID) { case NameServer_DID: @@ -1670,17 +1692,18 @@ lpfc_cmpl_adisc_adisc_issue(struct lpfc_vport *vport, { struct lpfc_hba *phba = vport->phba; struct lpfc_iocbq *cmdiocb, *rspiocb; - IOCB_t *irsp; ADISC *ap; int rc; + u32 ulp_status; cmdiocb = (struct lpfc_iocbq *) arg; rspiocb = cmdiocb->context_un.rsp_iocb; + ulp_status = get_job_ulpstatus(phba, rspiocb); + ap = (ADISC *)lpfc_check_elscmpl_iocb(phba, cmdiocb, rspiocb); - irsp = &rspiocb->iocb; - if ((irsp->ulpStatus) || + if ((ulp_status) || (!lpfc_check_adisc(vport, ndlp, &ap->nodeName, &ap->portName))) { /* 1 sec timeout */ mod_timer(&ndlp->nlp_delayfunc, @@ -2123,14 +2146,16 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, { struct lpfc_iocbq *cmdiocb, *rspiocb; struct lpfc_hba *phba = vport->phba; - IOCB_t *irsp; PRLI *npr; struct lpfc_nvme_prli *nvpr; void *temp_ptr; + u32 ulp_status; cmdiocb = (struct lpfc_iocbq *) arg; rspiocb = cmdiocb->context_un.rsp_iocb; + ulp_status = get_job_ulpstatus(phba, rspiocb); + /* A solicited PRLI is either FCP or NVME. The PRLI cmd/rsp * format is different so NULL the two PRLI types so that the * driver correctly gets the correct context. @@ -2138,13 +2163,12 @@ lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, npr = NULL; nvpr = NULL; temp_ptr = lpfc_check_elscmpl_iocb(phba, cmdiocb, rspiocb); - if (cmdiocb->iocb_flag & LPFC_PRLI_FCP_REQ) + if (cmdiocb->cmd_flag & LPFC_PRLI_FCP_REQ) npr = (PRLI *) temp_ptr; - else if (cmdiocb->iocb_flag & LPFC_PRLI_NVME_REQ) + else if (cmdiocb->cmd_flag & LPFC_PRLI_NVME_REQ) nvpr = (struct lpfc_nvme_prli *) temp_ptr; - irsp = &rspiocb->iocb; - if (irsp->ulpStatus) { + if (ulp_status) { if ((vport->port_type == LPFC_NPIV_PORT) && vport->cfg_restrict_login) { goto out; @@ -2743,16 +2767,18 @@ static uint32_t lpfc_cmpl_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, void *arg, uint32_t evt) { + struct lpfc_hba *phba = vport->phba; struct lpfc_iocbq *cmdiocb, *rspiocb; - IOCB_t *irsp; + u32 ulp_status; cmdiocb = (struct lpfc_iocbq *) arg; rspiocb = cmdiocb->context_un.rsp_iocb; - irsp = &rspiocb->iocb; - if (irsp->ulpStatus) { + ulp_status = get_job_ulpstatus(phba, rspiocb); + + if (ulp_status) return NLP_STE_FREED_NODE; - } + return ndlp->nlp_state; } @@ -2760,14 +2786,16 @@ static uint32_t lpfc_cmpl_prli_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, void *arg, uint32_t evt) { + struct lpfc_hba *phba = vport->phba; struct lpfc_iocbq *cmdiocb, *rspiocb; - IOCB_t *irsp; + u32 ulp_status; cmdiocb = (struct lpfc_iocbq *) arg; rspiocb = cmdiocb->context_un.rsp_iocb; - irsp = &rspiocb->iocb; - if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) { + ulp_status = get_job_ulpstatus(phba, rspiocb); + + if (ulp_status && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) { lpfc_drop_node(vport, ndlp); return NLP_STE_FREED_NODE; } @@ -2794,14 +2822,16 @@ static uint32_t lpfc_cmpl_adisc_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, void *arg, uint32_t evt) { + struct lpfc_hba *phba = vport->phba; struct lpfc_iocbq *cmdiocb, *rspiocb; - IOCB_t *irsp; + u32 ulp_status; cmdiocb = (struct lpfc_iocbq *) arg; rspiocb = cmdiocb->context_un.rsp_iocb; - irsp = &rspiocb->iocb; - if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) { + ulp_status = get_job_ulpstatus(phba, rspiocb); + + if (ulp_status && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) { lpfc_drop_node(vport, ndlp); return NLP_STE_FREED_NODE; } |