Re: [PATCH V2 0/5] lpfc 10.2.8001.0: Update lpfc to revision 10.2.8001.0
looks good Signed-By: Dick Kennedy -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V2 0/5] lpfc 10.2.8001.0: Update lpfc to revision 10.2.8001.0
Looks good. Reviewed-By: Dick Kennedy -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/1] Add defines for new FC port speeds.
These speeds are to support the next generation of FCoE port speeds. Signed-off-by: rkenn...@emulex.com --- drivers/scsi/scsi_transport_fc.c |4 include/scsi/scsi_transport_fc.h |4 2 files changed, 8 insertions(+), 0 deletions(-) diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index f80908f..454cc28 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -262,6 +262,10 @@ static const struct { { FC_PORTSPEED_8GBIT, "8 Gbit" }, { FC_PORTSPEED_16GBIT, "16 Gbit" }, { FC_PORTSPEED_32GBIT, "32 Gbit" }, + { FC_PORTSPEED_20GBIT, "20 Gbit" }, + { FC_PORTSPEED_40GBIT, "40 Gbit" }, + { FC_PORTSPEED_50GBIT, "50 Gbit" }, + { FC_PORTSPEED_100GBIT, "100 Gbit" }, { FC_PORTSPEED_NOT_NEGOTIATED, "Not Negotiated" }, }; fc_bitfield_name_search(port_speed, fc_port_speed_names) diff --git a/include/scsi/scsi_transport_fc.h b/include/scsi/scsi_transport_fc.h index 8c79980..007a0bc 100644 --- a/include/scsi/scsi_transport_fc.h +++ b/include/scsi/scsi_transport_fc.h @@ -131,6 +131,10 @@ enum fc_vport_state { #define FC_PORTSPEED_8GBIT 0x10 #define FC_PORTSPEED_16GBIT0x20 #define FC_PORTSPEED_32GBIT0x40 +#define FC_PORTSPEED_20GBIT0x80 +#define FC_PORTSPEED_40GBIT0x100 +#define FC_PORTSPEED_50GBIT0x200 +#define FC_PORTSPEED_100GBIT 0x400 #define FC_PORTSPEED_NOT_NEGOTIATED(1 << 15) /* Speed not established */ /* -- 1.6.6 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[lpfc 04/19] Fix PRLI ACC rsp for NVME
From: Dick Kennedy PRLI ACC from target is FCP oriented Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_els.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index d9c61d0..d6e0f58 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -4403,7 +4403,7 @@ lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb, pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt); memset(pcmd, 0, cmdsize); - *((uint32_t *) (pcmd)) = (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK)); + *((uint32_t *)(pcmd)) = elsrspcmd; pcmd += sizeof(uint32_t); /* For PRLI, remainder of payload is PRLI parameter page */ -- 2.1.0
[lpfc 19/19] lpfc revison 11.2.0.12
From: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index d4e95e2..1c26dc6 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -20,7 +20,7 @@ * included with this package. * ***/ -#define LPFC_DRIVER_VERSION "11.2.0.10" +#define LPFC_DRIVER_VERSION "11.2.0.12" #define LPFC_DRIVER_NAME "lpfc" /* Used for SLI 2/3 */ -- 2.1.0
[lpfc 11/19] Add NVMET changes to interface with 4.11 kernel
From: Dick Kennedy --- drivers/scsi/lpfc/lpfc_nvmet.c | 127 - drivers/scsi/lpfc/lpfc_nvmet.h | 7 ++- 2 files changed, 105 insertions(+), 29 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index 551e81a..cbd6371 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c @@ -408,9 +408,7 @@ out: if (phba->ktime_on) lpfc_nvmet_ktime(phba, ctxp); #endif - /* Let Abort cmpl repost the context */ - if (!(ctxp->flag & LPFC_NVMET_ABORT_OP)) - lpfc_nvmet_rq_post(phba, ctxp, &ctxp->rqb_buffer->hbuf); + /* lpfc_nvmet_xmt_fcp_release() will recycle the context */ } else { ctxp->entry_cnt++; start_clean = offsetof(struct lpfc_iocbq, wqe); @@ -543,27 +541,6 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport, } #endif - if (rsp->op == NVMET_FCOP_ABORT) { - lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS, - "6103 Abort op: oxri x%x %d cnt %d\n", - ctxp->oxid, ctxp->state, ctxp->entry_cnt); - - lpfc_nvmeio_data(phba, "NVMET FCP ABRT: " -"xri x%x state x%x cnt x%x\n", -ctxp->oxid, ctxp->state, ctxp->entry_cnt); - - atomic_inc(&lpfc_nvmep->xmt_fcp_abort); - ctxp->entry_cnt++; - ctxp->flag |= LPFC_NVMET_ABORT_OP; - if (ctxp->flag & LPFC_NVMET_IO_INP) - lpfc_nvmet_sol_fcp_issue_abort(phba, ctxp, ctxp->sid, - ctxp->oxid); - else - lpfc_nvmet_unsol_fcp_issue_abort(phba, ctxp, ctxp->sid, -ctxp->oxid); - return 0; - } - /* Sanity check */ if (ctxp->state == LPFC_NVMET_STE_ABORT) { atomic_inc(&lpfc_nvmep->xmt_fcp_drop); @@ -630,10 +607,76 @@ lpfc_nvmet_targetport_delete(struct nvmet_fc_target_port *targetport) complete(&tport->tport_unreg_done); } +static void +lpfc_nvmet_xmt_fcp_abort(struct nvmet_fc_target_port *tgtport, +struct nvmefc_tgt_fcp_req *req) +{ + struct lpfc_nvmet_tgtport *lpfc_nvmep = tgtport->private; + struct lpfc_nvmet_rcv_ctx *ctxp = + container_of(req, struct lpfc_nvmet_rcv_ctx, ctx.fcp_req); + struct lpfc_hba *phba = ctxp->phba; + + lpfc_printf_log(phba, KERN_INFO, LOG_NVME_ABTS, + "6103 Abort op: oxri x%x %d cnt %d\n", + ctxp->oxid, ctxp->state, ctxp->entry_cnt); + + lpfc_nvmeio_data(phba, "NVMET FCP ABRT: " +"xri x%x state x%x cnt x%x\n", +ctxp->oxid, ctxp->state, ctxp->entry_cnt); + + atomic_inc(&lpfc_nvmep->xmt_fcp_abort); + ctxp->entry_cnt++; + ctxp->flag |= LPFC_NVMET_ABORT_OP; + if (ctxp->flag & LPFC_NVMET_IO_INP) + lpfc_nvmet_sol_fcp_issue_abort(phba, ctxp, ctxp->sid, + ctxp->oxid); + else + lpfc_nvmet_unsol_fcp_issue_abort(phba, ctxp, ctxp->sid, +ctxp->oxid); +} + +static void +lpfc_nvmet_xmt_fcp_release(struct nvmet_fc_target_port *tgtport, + struct nvmefc_tgt_fcp_req *rsp) +{ + struct lpfc_nvmet_tgtport *lpfc_nvmep = tgtport->private; + struct lpfc_nvmet_rcv_ctx *ctxp = + container_of(rsp, struct lpfc_nvmet_rcv_ctx, ctx.fcp_req); + struct lpfc_hba *phba = ctxp->phba; + unsigned long flags; + bool aborting = false; + + spin_lock_irqsave(&ctxp->ctxlock, flags); + if (ctxp->flag & LPFC_NVMET_ABORT_OP) { + aborting = true; + ctxp->flag |= LPFC_NVMET_CTX_RLS; + } + spin_unlock_irqrestore(&ctxp->ctxlock, flags); + + if (aborting) + /* let the abort path do the real release */ + return; + + /* Sanity check */ + if (ctxp->state != LPFC_NVMET_STE_DONE) { + atomic_inc(&lpfc_nvmep->xmt_fcp_drop); + lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR, + "6117 Bad state IO x%x aborted\n", + ctxp->oxid); + } + + lpfc_nvmeio_data(phba, "NVMET FCP FREE: xri x%x ste %d\n", ctxp->oxid, +ctxp->state, 0); + + lpfc_nvmet_rq_post(p
[lpfc 00/19] lpfc updates.
This patch set includes patches to fix driver load/unload that have been partiallty submitted by other users. This patch set is supplying the abort handline for nvme that was missing. Dick Kennedy (19): Fix advertised max_sgl_segment count for NVMET Fixes after reviewing last set of patches. Minor fixes to previous patches Fix spelling in comments. Fix PRLI ACC rsp for NVME Fix driver unload/reload operation. Fix discovery error handling in NVME initiator Fix driver usage of 128B WQEs when WQ_CREATE is V1. Fix nvme initiator handling when CONFIG_LPFC_NVME_INITIATOR is not enabled. Fix Kconfig defines. Remove hba lock from NVMET isssue WQE Add NVMET changes to interface with 4.11 kernel cannot establish connection with target that sends PRLI in PT2PT Fix driver load issues when MRQ=8 Fix crash after issuing lip reset Fix max_sgl_segments settings for NVME / NVMET Add Fabric assigned WWN support. Fix implicit logo and RSCN handling for NVMET Update ABORT processing for NVMET lpfc revison 11.2.0.12 drivers/scsi/lpfc/lpfc.h | 5 +- drivers/scsi/lpfc/lpfc_attr.c | 16 +- drivers/scsi/lpfc/lpfc_bsg.c | 4 + drivers/scsi/lpfc/lpfc_crtn.h | 9 +- drivers/scsi/lpfc/lpfc_ct.c| 68 -- drivers/scsi/lpfc/lpfc_debugfs.c | 69 -- drivers/scsi/lpfc/lpfc_disc.h | 1 + drivers/scsi/lpfc/lpfc_els.c | 68 +++--- drivers/scsi/lpfc/lpfc_hbadisc.c | 131 +++ drivers/scsi/lpfc/lpfc_hw.h| 3 + drivers/scsi/lpfc/lpfc_hw4.h | 4 + drivers/scsi/lpfc/lpfc_init.c | 169 ++- drivers/scsi/lpfc/lpfc_mbox.c | 7 +- drivers/scsi/lpfc/lpfc_nportdisc.c | 8 +- drivers/scsi/lpfc/lpfc_nvme.c | 139 drivers/scsi/lpfc/lpfc_nvme.h | 7 +- drivers/scsi/lpfc/lpfc_nvmet.c | 434 ++--- drivers/scsi/lpfc/lpfc_nvmet.h | 13 +- drivers/scsi/lpfc/lpfc_sli.c | 22 +- drivers/scsi/lpfc/lpfc_sli4.h | 2 +- drivers/scsi/lpfc/lpfc_version.h | 2 +- drivers/scsi/lpfc/lpfc_vport.c | 3 +- 22 files changed, 870 insertions(+), 314 deletions(-) -- 2.1.0
[lpfc 16/19] Add Fabric assigned WWN support.
From: Dick Kennedy Firmware sends first FLOGI to fabric with vendor version changes. On link up driver gets updated service parameter with FAWWN assigned port name. Driver sends 2nd FLOGI with updated fawwpn and modifies the vport->fc_portname i n driver. Soft wwpn will not be allowed when fawwpn is enabled. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc.h | 2 ++ drivers/scsi/lpfc/lpfc_attr.c| 8 drivers/scsi/lpfc/lpfc_els.c | 8 +--- drivers/scsi/lpfc/lpfc_hbadisc.c | 22 +- drivers/scsi/lpfc/lpfc_hw.h | 3 +++ drivers/scsi/lpfc/lpfc_hw4.h | 1 + drivers/scsi/lpfc/lpfc_init.c| 31 --- 7 files changed, 64 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 0fc1450..6d7840b 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -474,6 +474,8 @@ struct lpfc_vport { unsigned long rcv_buffer_time_stamp; uint32_t vport_flag; #define STATIC_VPORT 1 +#define FAWWPN_SET 2 +#define FAWWPN_PARAM_CHG 4 uint16_t fdmi_num_disc; uint32_t fdmi_hba_mask; diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 0e28c2e..69a0039 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -2292,6 +2292,8 @@ lpfc_soft_wwn_enable_store(struct device *dev, struct device_attribute *attr, struct lpfc_vport *vport = (struct lpfc_vport *) shost->hostdata; struct lpfc_hba *phba = vport->phba; unsigned int cnt = count; + uint8_t vvvl = vport->fc_sparam.cmn.valid_vendor_ver_level; + uint32_t *fawwpn_key = (uint32_t *)&vport->fc_sparam.un.vendorVersion[0]; /* * We're doing a simple sanity check for soft_wwpn setting. @@ -2305,6 +2307,12 @@ lpfc_soft_wwn_enable_store(struct device *dev, struct device_attribute *attr, * here. The intent is to protect against the random user or * application that is just writing attributes. */ + if (vvvl == 1 && (cpu_to_be32(*fawwpn_key)) == FAPWWN_KEY_VENDOR) { + lpfc_printf_log(phba, KERN_ERR, LOG_INIT, +"0051 "LPFC_DRIVER_NAME" soft wwpn can not" +" be enabled: fawwpn is enabled\n"); + return -EPERM; + } /* count may include a LF at end of string */ if (buf[cnt-1] == '\n') diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index ffdcac0..35fc260 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -603,9 +603,11 @@ lpfc_check_clean_addr_bit(struct lpfc_vport *vport, memcmp(&vport->fabric_portname, &sp->portName, sizeof(struct lpfc_name)) || memcmp(&vport->fabric_nodename, &sp->nodeName, - sizeof(struct lpfc_name))) + sizeof(struct lpfc_name)) || + (vport->vport_flag & FAWWPN_PARAM_CHG)) { fabric_param_changed = 1; - + vport->vport_flag &= ~FAWWPN_PARAM_CHG; + } /* * Word 1 Bit 31 in common service parameter is overloaded. * Word 1 Bit 31 in FLOGI request is multiple NPort request @@ -8755,7 +8757,7 @@ lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, pcmd += sizeof(uint32_t); /* Node Name */ pcmd += sizeof(uint32_t); /* Node Name */ memcpy(pcmd, &vport->fc_nodename, 8); - + memset(sp->un.vendorVersion, 0, sizeof(sp->un.vendorVersion)); lpfc_set_disctmo(vport); phba->fc_stat.elsXmitFDISC++; diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index d313dde..e824ec1 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -3002,6 +3002,7 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) MAILBOX_t *mb = &pmb->u.mb; struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) pmb->context1; struct lpfc_vport *vport = pmb->vport; + struct Scsi_Host *shost = lpfc_shost_from_vport(vport); struct serv_parm *sp = &vport->fc_sparam; uint32_t ed_tov; @@ -3031,6 +3032,7 @@ lpfc_mbx_cmpl_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) } lpfc_update_vport_wwn(vport); + fc_host_port_name(shost) = wwn_to_u64(vport->fc_portname.u.wwn); if (vport->port_type == LPFC_PHYSICAL_PORT) { memcpy(&phba->wwnn, &vport->fc_nodename, sizeof(phba->wwnn)); memcpy(&phba->wwpn, &vport->fc_portname, sizeof(phba->wwnn)); @@ -3309,6 +3311,7 @@ lpfc_mbx_cmpl_read_topol
[lpfc 12/19] cannot establish connection with target that sends PRLI in PT2PT
From: Dick Kennedy The driver does not accept PRLI from the target and this causes the target to reject the subsequent PRLI from the driver Fix: Accept the incoming PRLI so that the target can also accept the PRLI from the driver Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_init.c | 12 drivers/scsi/lpfc/lpfc_nvme.c | 23 --- drivers/scsi/lpfc/lpfc_nvmet.c | 6 +++--- 3 files changed, 23 insertions(+), 18 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index cca7f81..88977b8 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -11061,7 +11061,7 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) struct lpfc_hba *phba; struct lpfc_vport *vport = NULL; struct Scsi_Host *shost = NULL; - int error; + int error, cnt; uint32_t cfg_mode, intr_mode; /* Allocate memory for HBA structure */ @@ -11095,11 +11095,15 @@ lpfc_pci_probe_one_s4(struct pci_dev *pdev, const struct pci_device_id *pid) goto out_unset_pci_mem_s4; } + cnt = phba->cfg_iocb_cnt * 1024; + if (phba->nvmet_support) + cnt += (phba->cfg_nvmet_mrq_post * phba->cfg_nvmet_mrq); + /* Initialize and populate the iocb list per host */ lpfc_printf_log(phba, KERN_INFO, LOG_INIT, - "2821 initialize iocb list %d.\n", - phba->cfg_iocb_cnt*1024); - error = lpfc_init_iocb_list(phba, phba->cfg_iocb_cnt*1024); + "2821 initialize iocb list %d total %d\n", + phba->cfg_iocb_cnt, cnt); + error = lpfc_init_iocb_list(phba, cnt); if (error) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 9d39093..9468679 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -1495,6 +1495,7 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, "io buffer. Skipping abort req.\n"); return; } + nvmereq_wqe = &lpfc_nbuf->cur_iocbq; /* * The lpfc_nbuf and the mapped nvme_fcreq in the driver's @@ -1508,20 +1509,19 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME, "6143 NVME req mismatch: " "lpfc_nbuf %p nvmeCmd %p, " -"pnvme_fcreq %p. Skipping Abort\n", +"pnvme_fcreq %p. Skipping Abort xri x%x\n", lpfc_nbuf, lpfc_nbuf->nvmeCmd, -pnvme_fcreq); +pnvme_fcreq, nvmereq_wqe->sli4_xritag); return; } /* Don't abort IOs no longer on the pending queue. */ - nvmereq_wqe = &lpfc_nbuf->cur_iocbq; if (!(nvmereq_wqe->iocb_flag & LPFC_IO_ON_TXCMPLQ)) { spin_unlock_irqrestore(&phba->hbalock, flags); lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME, "6142 NVME IO req %p not queued - skipping " -"abort req\n", -pnvme_fcreq); +"abort req xri x%x\n", +pnvme_fcreq, nvmereq_wqe->sli4_xritag); return; } @@ -1535,8 +1535,9 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME, "6144 Outstanding NVME I/O Abort Request " "still pending on nvme_fcreq %p, " -"lpfc_ncmd %p\n", -pnvme_fcreq, lpfc_nbuf); +"lpfc_ncmd %p xri x%x\n", +pnvme_fcreq, lpfc_nbuf, +nvmereq_wqe->sli4_xritag); return; } @@ -1545,8 +1546,8 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, spin_unlock_irqrestore(&phba->hbalock, flags); lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME, "6136 No available abort wqes. Skipping " -"Abts req for nvme_fcreq %p.\n", -pnvme_fcreq); +"Abts req for nvme_fcreq %p xri x%x\n", +pnvme_fcreq, nv
[lpfc 08/19] Fix nvme initiator handling when CONFIG_LPFC_NVME_INITIATOR is not enabled.
From: Dick Kennedy With update nvme upstream driver sources, loading the driver with nvme enabled resulting in this Oops. Mar 6 10:09:55 NVME-init kernel: BUG: unable to handle kernel NULL pointer dere ference at 0018 Mar 6 10:09:55 NVME-init kernel: IP: lpfc_nvme_update_localport+0x23/0xd0 [lpfc ] Mar 6 10:09:55 NVME-init kernel: PGD 0 Mar 6 10:09:55 NVME-init kernel: Mar 6 10:09:55 NVME-init kernel: Oops: [#1] SMP Mar 6 10:09:55 NVME-init kernel: CPU: 0 PID: 10256 Comm: lpfc_worker_0 Tainted: G O4.10.0-rc7 #1 Mar 6 10:09:55 NVME-init kernel: Hardware name: Supermicro Super Server/X10DRL- i, BIOS 2.0 12/18/2015 Mar 6 10:09:55 NVME-init kernel: task: 881028191c40 task.stack: 880ffdf 0 Mar 6 10:09:55 NVME-init kernel: RIP: 0010:lpfc_nvme_update_localport+0x23/0xd0 [lpfc] Mar 6 10:09:55 NVME-init kernel: RSP: 0018:880ffdf03c20 EFLAGS: 00010202 Mar 6 10:09:55 NVME-init kernel: RAX: 0003 RBX: 88103285b7d0 RC X: 0001 Mar 6 10:09:55 NVME-init kernel: RDX: 881031c13400 RSI: 0292 RD I: 88103285b7d0 Mar 6 10:09:55 NVME-init kernel: RBP: 880ffdf03c40 R08: 00fc R0 9: 880fff6c66c0 Mar 6 10:09:55 NVME-init kernel: R10: 880fff01f200 R11: 880fff6c6680 R1 2: Mar 6 10:09:55 NVME-init kernel: R13: 8810308ac000 R14: R1 5: 0028 Mar 6 10:09:55 NVME-init kernel: FS: () GS:88103f2 0() knlGS: Mar 6 10:09:55 NVME-init kernel: CS: 0010 DS: ES: CR0: 80050 033 Mar 6 10:09:55 NVME-init kernel: CR2: 0018 CR3: 01009000 CR 4: 001406f0 Cause: As the initiator driver completes discovery at different stages, it call lpfc_nvme_update_localport to hint that the DID and role may have changed. In the implementation of lpfc_nvme_update_localport, the driver was not validating the localport or the lport during the execution of the update_localport routine. With the recent upstream additions to the driver, the create_localport routine didn't run and so the localport was NULL causing the page-fault Oops. Fix: Add the CONFIG_LPFC_NVME_INITIATOR preprocessor inclusions to lpfc_nvme_update_localport to turn off all routine processing when the running kernel does not have NVME configured. Add NULL pointer checks on the localport and lport in lpfc_nvme_update_localport and dump messages if they are NULL and just exit. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_nvme.c | 15 +-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 6465aa6..9726c95 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -2264,12 +2264,23 @@ lpfc_nvme_destroy_localport(struct lpfc_vport *vport) void lpfc_nvme_update_localport(struct lpfc_vport *vport) { +#ifdef CONFIG_LPFC_NVME_INITIATOR struct nvme_fc_local_port *localport; struct lpfc_nvme_lport *lport; localport = vport->localport; + if (!localport) { + lpfc_printf_vlog(vport, KERN_WARNING, LOG_NVME, +"6710 Update NVME fail. No localport\n"); + return; + } lport = (struct lpfc_nvme_lport *)localport->private; - + if (!lport) { + lpfc_printf_vlog(vport, KERN_WARNING, LOG_NVME, +"6171 Update NVME fail. localP %p, No lport\n", +localport); + return; + } lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME, "6012 Update NVME lport %p did x%x\n", localport, vport->fc_myDID); @@ -2283,7 +2294,7 @@ lpfc_nvme_update_localport(struct lpfc_vport *vport) lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, "6030 bound lport %p to DID x%06x\n", lport, localport->port_id); - +#endif } int -- 2.1.0
[lpfc 15/19] Fix max_sgl_segments settings for NVME / NVMET
From: Dick Kennedy Cannot set these to a large number The existing module parameter lpfc_sg_seg_cnt is used for both SCSI and NVME. Limit the module parameter lpfc_sg_seg_cnt to 128 with the default being 64 for both NVME and NVMET, assuming NVME is enabled in the driver for that port. The driver will set max_sgl_segments in the NVME/NVMET template to lpfc_sg_seg_cnt + 1. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc.h | 3 ++- drivers/scsi/lpfc/lpfc_nvme.c | 18 ++ drivers/scsi/lpfc/lpfc_nvmet.c | 19 +++ 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h index 257bbdd..0fc1450 100644 --- a/drivers/scsi/lpfc/lpfc.h +++ b/drivers/scsi/lpfc/lpfc.h @@ -56,7 +56,7 @@ struct lpfc_sli2_slim; #define LPFC_MAX_SG_SEG_CNT4096/* sg element count per scsi cmnd */ #define LPFC_MAX_SGL_SEG_CNT 512 /* SGL element count per scsi cmnd */ #define LPFC_MAX_BPL_SEG_CNT 4096/* BPL element count per scsi cmnd */ -#define LPFC_MIN_NVME_SEG_CNT 254 +#define LPFC_MAX_NVME_SEG_CNT 128 /* max SGL element cnt per NVME cmnd */ #define LPFC_MAX_SGE_SIZE 0x8000 /* Maximum data allowed in a SGE */ #define LPFC_IOCB_LIST_CNT 2250/* list of IOCBs for fast-path usage. */ @@ -781,6 +781,7 @@ struct lpfc_hba { uint32_t cfg_nvmet_fb_size; uint32_t cfg_total_seg_cnt; uint32_t cfg_sg_seg_cnt; + uint32_t cfg_nvme_seg_cnt; uint32_t cfg_sg_dma_buf_size; uint64_t cfg_soft_wwnn; uint64_t cfg_soft_wwpn; diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 5145ef2..01cefaf 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -1114,12 +1114,12 @@ lpfc_nvme_prep_io_dma(struct lpfc_vport *vport, first_data_sgl = sgl; lpfc_ncmd->seg_cnt = nCmd->sg_cnt; - if (lpfc_ncmd->seg_cnt > phba->cfg_sg_seg_cnt) { + if (lpfc_ncmd->seg_cnt > phba->cfg_nvme_seg_cnt) { lpfc_printf_log(phba, KERN_ERR, LOG_NVME_IOERR, "6058 Too many sg segments from " "NVME Transport. Max %d, " "nvmeIO sg_cnt %d\n", - phba->cfg_sg_seg_cnt, + phba->cfg_nvme_seg_cnt, lpfc_ncmd->seg_cnt); lpfc_ncmd->seg_cnt = 0; return 1; @@ -2159,8 +2159,18 @@ lpfc_nvme_create_localport(struct lpfc_vport *vport) nfcp_info.node_name = wwn_to_u64(vport->fc_nodename.u.wwn); nfcp_info.port_name = wwn_to_u64(vport->fc_portname.u.wwn); - /* For now need + 1 to get around NVME transport logic */ - lpfc_nvme_template.max_sgl_segments = phba->cfg_sg_seg_cnt + 1; + /* Limit to LPFC_MAX_NVME_SEG_CNT. +* For now need + 1 to get around NVME transport logic. +*/ + if (phba->cfg_sg_seg_cnt > LPFC_MAX_NVME_SEG_CNT) { + lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME | LOG_INIT, +"6300 Reducing sg segment cnt to %d\n", +LPFC_MAX_NVME_SEG_CNT); + phba->cfg_nvme_seg_cnt = LPFC_MAX_NVME_SEG_CNT; + } else { + phba->cfg_nvme_seg_cnt = phba->cfg_sg_seg_cnt; + } + lpfc_nvme_template.max_sgl_segments = phba->cfg_nvme_seg_cnt + 1; lpfc_nvme_template.max_hw_queues = phba->cfg_nvme_io_channel; /* localport is allocated from the stack, but the registration diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index 3a0ff50..ea7a5b2 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c @@ -705,8 +705,19 @@ lpfc_nvmet_create_targetport(struct lpfc_hba *phba) pinfo.port_name = wwn_to_u64(vport->fc_portname.u.wwn); pinfo.port_id = vport->fc_myDID; + /* Limit to LPFC_MAX_NVME_SEG_CNT. +* For now need + 1 to get around NVME transport logic. +*/ + if (phba->cfg_sg_seg_cnt > LPFC_MAX_NVME_SEG_CNT) { + lpfc_printf_log(phba, KERN_INFO, LOG_NVME | LOG_INIT, + "6400 Reducing sg segment cnt to %d\n", + LPFC_MAX_NVME_SEG_CNT); + phba->cfg_nvme_seg_cnt = LPFC_MAX_NVME_SEG_CNT; + } else { + phba->cfg_nvme_seg_cnt = phba->cfg_sg_seg_cnt; + } + lpfc_tgttemplate.max_sgl_segments = phba->cfg_nvme_seg_cnt + 1; lpfc_tgttemplate.max_hw_queues = phba->cfg_nvme_io_channel
[lpfc 06/19] Fix discovery error handling in NVME initiator
From: Dick Kennedy performance lab running tests on upstream 4.10-rc5 POC and observing error during the NVME connect process. Here are the errors: Issue 1: The initiator is claiming the nvme_fc_unregister_remoteport upcall is not completing the unregister in the time allotted. [ 2186.151317] lpfc :07:00.0: 0:(0):6169 Unreg nvme wait failed 0 Issue 2: In this case, the NVME initiator is sending an LS REQ command on an NDLP that is not MAPPED. The FW rejects it. [ 2186.165689] lpfc :07:00.0: 0:(0):6051 ENTER. lport 8817c75f7f00, rport 8817d2ab3bc0 lsreq8817cdad1900 rqstlen:48 rsplen:24 102234921368x 102234921416 [ 2186.165691] lpfc :07:00.0: 0:(0):6050 Issue GEN REQ WQE to NPORT x560100 Data: x7a5 x20 wq:8817c7f5ce00 lsreq:8817cdad1900 bmp:8817c7492400 xmit:48 1st:48 [ 2186.165700] lpfc :07:00.0: 0:(0):6047 nvme cmpl Enter Data 8817cdad1900 DID 560100 Xri: 3d status 3 cmd:8817c7f5ce00 lsreg:8817cdad1900 bmp:8817c7492400 ndlp:8817c8c4b600 Issue 3: There is a panic in the lpfc_nvme_io_cmd_wqe_cmpl routine whenever the NVME IO logging is enabled. This is because the initiator is touching the NDLP post unregister. Cause: Summarized: Issue 1: The wait_for_completion_timeout returns 0 when the wait has been outstanding for the jiffies passed by the caller. In this error message, the nvme initiator passed value 5 - meaning 5 jiffies - and this is just wrong. Issue 2: The lpfc_nvme_ls_req routine checks for a NULL ndlp pointer but does not check the NDLP state. This allows the routine to send an LS IO when the ndlp is disconnected. Issue 3: The driver checks for NULL pointers but the log message in the driver references the null ndlp anyway. Fix: Summarized: Issue 1: Calculate 5 seconds in Jiffies and pass that value from the current jiffies. Issue 2: Check the ndlp for NULL, actual node, Target and MAPPED or Initiator and UNMAPPED. This avoids Fabric nodes getting the Create Association or Create Connection commands. Initiators are free to Reject either Create. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_nvme.c | 37 +++-- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 0024de1..6465aa6 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -417,11 +417,26 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport, vport = lport->vport; ndlp = lpfc_findnode_did(vport, pnvme_rport->port_id); - if (!ndlp) { - lpfc_printf_vlog(vport, KERN_ERR, LOG_NVME_DISC, -"6043 Could not find node for DID %x\n", + if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { + lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE | LOG_NVME_IOERR, +"6051 DID x%06x not an active rport.\n", pnvme_rport->port_id); - return 1; + return -ENODEV; + } + + /* The remote node has to be a mapped nvme target or an +* unmapped nvme initiator or it's an error. +*/ + if (((ndlp->nlp_type & NLP_NVME_TARGET) && +(ndlp->nlp_state != NLP_STE_MAPPED_NODE)) || + ((ndlp->nlp_type & NLP_NVME_INITIATOR) && +(ndlp->nlp_state != NLP_STE_UNMAPPED_NODE))) { + lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE | LOG_NVME_IOERR, +"6088 DID x%06x not ready for " +"IO. State x%x, Type x%x\n", +pnvme_rport->port_id, +ndlp->nlp_state, ndlp->nlp_type); + return -ENODEV; } bmp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL); if (!bmp) { @@ -456,7 +471,7 @@ lpfc_nvme_ls_req(struct nvme_fc_local_port *pnvme_lport, /* Expand print to include key fields. */ lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC, -"6051 ENTER. lport %p, rport %p lsreq%p rqstlen:%d " +"6149 ENTER. lport %p, rport %p lsreq%p rqstlen:%d " "rsplen:%d %pad %pad\n", pnvme_lport, pnvme_rport, pnvme_lsreq, pnvme_lsreq->rqstlen, @@ -772,9 +787,9 @@ lpfc_nvme_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn, ndlp = rport->ndlp; if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) { lpfc_printf_vlog(vport, KERN_ERR, LOG_NODE | LOG_NVME_IOERR, -"6061 rport %p, ndlp %p, DID x%06x ndlp " +"6061 rport %p, DID x%06x node " &q
[lpfc 18/19] Update ABORT processing for NVMET
From: Dick Kennedy Missing code path, new NVME abort API The first lpfc driver with nvme had this routine stubbed. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_crtn.h| 7 + drivers/scsi/lpfc/lpfc_debugfs.c | 55 +-- drivers/scsi/lpfc/lpfc_hw4.h | 3 + drivers/scsi/lpfc/lpfc_init.c| 52 +++--- drivers/scsi/lpfc/lpfc_mbox.c| 7 +- drivers/scsi/lpfc/lpfc_nvme.c| 45 +++-- drivers/scsi/lpfc/lpfc_nvmet.c | 348 +++ drivers/scsi/lpfc/lpfc_nvmet.h | 10 +- drivers/scsi/lpfc/lpfc_sli.c | 7 +- drivers/scsi/lpfc/lpfc_sli4.h| 2 +- 10 files changed, 411 insertions(+), 125 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index d859aff..24da922 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -24,6 +24,7 @@ typedef int (*node_filter)(struct lpfc_nodelist *, void *); struct fc_rport; struct fc_frame_header; +struct lpfc_nvmet_rcv_ctx; void lpfc_down_link(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_sli_read_link_ste(struct lpfc_hba *); void lpfc_dump_mem(struct lpfc_hba *, LPFC_MBOXQ_t *, uint16_t, uint16_t); @@ -245,6 +246,10 @@ struct hbq_dmabuf *lpfc_sli4_rb_alloc(struct lpfc_hba *); void lpfc_sli4_rb_free(struct lpfc_hba *, struct hbq_dmabuf *); struct rqb_dmabuf *lpfc_sli4_nvmet_alloc(struct lpfc_hba *phba); void lpfc_sli4_nvmet_free(struct lpfc_hba *phba, struct rqb_dmabuf *dmab); +void lpfc_nvmet_rq_post(struct lpfc_hba *phba, struct lpfc_nvmet_rcv_ctx *ctxp, + struct lpfc_dmabuf *mp); +int lpfc_nvmet_rcv_unsol_abort(struct lpfc_vport *vport, + struct fc_frame_header *fc_hdr); void lpfc_sli4_build_dflt_fcf_record(struct lpfc_hba *, struct fcf_record *, uint16_t); int lpfc_sli4_rq_put(struct lpfc_queue *hq, struct lpfc_queue *dq, @@ -302,6 +307,8 @@ int lpfc_sli_check_eratt(struct lpfc_hba *); void lpfc_sli_handle_slow_ring_event(struct lpfc_hba *, struct lpfc_sli_ring *, uint32_t); void lpfc_sli4_handle_received_buffer(struct lpfc_hba *, struct hbq_dmabuf *); +void lpfc_sli4_seq_abort_rsp(struct lpfc_vport *vport, +struct fc_frame_header *fc_hdr, bool aborted); void lpfc_sli_def_mbox_cmpl(struct lpfc_hba *, LPFC_MBOXQ_t *); void lpfc_sli4_unreg_rpi_cmpl_clr(struct lpfc_hba *, LPFC_MBOXQ_t *); int lpfc_sli_issue_iocb(struct lpfc_hba *, uint32_t, diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 55a8d8f..67efa68 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -745,73 +745,104 @@ lpfc_debugfs_nvmestat_data(struct lpfc_vport *vport, char *buf, int size) { struct lpfc_hba *phba = vport->phba; struct lpfc_nvmet_tgtport *tgtp; + struct lpfc_nvmet_rcv_ctx *ctxp, *next_ctxp; int len = 0; + int cnt; if (phba->nvmet_support) { if (!phba->targetport) return len; tgtp = (struct lpfc_nvmet_tgtport *)phba->targetport->private; - len += snprintf(buf+len, size-len, + len += snprintf(buf + len, size - len, "\nNVME Targetport Statistics\n"); - len += snprintf(buf+len, size-len, + len += snprintf(buf + len, size - len, "LS: Rcv %08x Drop %08x Abort %08x\n", atomic_read(&tgtp->rcv_ls_req_in), atomic_read(&tgtp->rcv_ls_req_drop), atomic_read(&tgtp->xmt_ls_abort)); if (atomic_read(&tgtp->rcv_ls_req_in) != atomic_read(&tgtp->rcv_ls_req_out)) { - len += snprintf(buf+len, size-len, + len += snprintf(buf + len, size - len, "Rcv LS: in %08x != out %08x\n", atomic_read(&tgtp->rcv_ls_req_in), atomic_read(&tgtp->rcv_ls_req_out)); } - len += snprintf(buf+len, size-len, + len += snprintf(buf + len, size - len, "LS: Xmt %08x Drop %08x Cmpl %08x Err %08x\n", atomic_read(&tgtp->xmt_ls_rsp), atomic_read(&tgtp->xmt_ls_drop), atomic_read(&tgtp->xmt_ls_rsp_cmpl), atomic_read(&tgtp->xmt_ls_rsp_error)); - len += snprintf(buf+len, size-len, + len += snprintf(buf + len, size - len, "FCP: Rcv %08x Drop %08x\n&
[lpfc 02/19] Fixes after reviewing last set of patches. Minor fixes to previous patches
From: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_attr.c| 6 +- drivers/scsi/lpfc/lpfc_debugfs.c | 14 -- drivers/scsi/lpfc/lpfc_init.c| 6 ++ drivers/scsi/lpfc/lpfc_nvme.h| 3 --- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 22819af..9e66cb0 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -4458,7 +4458,11 @@ lpfc_fcp_imax_store(struct device *dev, struct device_attribute *attr, phba->cfg_fcp_imax = (uint32_t)val; - for (i = 0; i < phba->io_channel_irqs; i += LPFC_MAX_EQ_DELAY_EQID_CNT) + /* +* Configure EQ delay multipier for interrupt coalescing using +* MODIFY_EQ_DELAY for all EQs created, LPFC_MAX_EQ_DELAY at a time. +*/ + for (i = 0; i < phba->io_channel_irqs; i += LPFC_MAX_EQ_DELAY) lpfc_modify_hba_eq_delay(phba, i); return strlen(buf); diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 913eed8..55a8d8f 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c @@ -3128,8 +3128,6 @@ __lpfc_idiag_print_rqpair(struct lpfc_queue *qp, struct lpfc_queue *datqp, datqp->queue_id, datqp->entry_count, datqp->entry_size, datqp->host_index, datqp->hba_index); - len += snprintf(pbuffer + len, LPFC_QUE_INFO_GET_BUF_SIZE - len, "\n"); - return len; } @@ -5700,10 +5698,8 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport) #ifdef CONFIG_SCSI_LPFC_DEBUG_FS struct lpfc_hba *phba = vport->phba; - if (vport->disc_trc) { - kfree(vport->disc_trc); - vport->disc_trc = NULL; - } + kfree(vport->disc_trc); + vport->disc_trc = NULL; debugfs_remove(vport->debug_disc_trc); /* discovery_trace */ vport->debug_disc_trc = NULL; @@ -5770,10 +5766,8 @@ lpfc_debugfs_terminate(struct lpfc_vport *vport) debugfs_remove(phba->debug_readRef); /* readRef */ phba->debug_readRef = NULL; - if (phba->slow_ring_trc) { - kfree(phba->slow_ring_trc); - phba->slow_ring_trc = NULL; - } + kfree(phba->slow_ring_trc); + phba->slow_ring_trc = NULL; /* slow_ring_trace */ debugfs_remove(phba->debug_slow_ring_trc); diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 6cc561b..b56da01 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -3508,6 +3508,12 @@ lpfc_sli4_scsi_sgl_update(struct lpfc_hba *phba) spin_unlock(&phba->scsi_buf_list_put_lock); spin_unlock_irq(&phba->scsi_buf_list_get_lock); + lpfc_printf_log(phba, KERN_INFO, LOG_SLI, + "6060 Current allocated SCSI xri-sgl count:%d, " + "maximum SCSI xri count:%d (split:%d)\n", + phba->sli4_hba.scsi_xri_cnt, + phba->sli4_hba.scsi_xri_max, phba->cfg_xri_split); + if (phba->sli4_hba.scsi_xri_cnt > phba->sli4_hba.scsi_xri_max) { /* max scsi xri shrinked below the allocated scsi buffers */ scsi_xri_cnt = phba->sli4_hba.scsi_xri_cnt - diff --git a/drivers/scsi/lpfc/lpfc_nvme.h b/drivers/scsi/lpfc/lpfc_nvme.h index 6277796..2582f46 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.h +++ b/drivers/scsi/lpfc/lpfc_nvme.h @@ -22,9 +22,6 @@ / #define LPFC_NVME_DEFAULT_SEGS (64 + 1)/* 256K IOs */ -#define LPFC_NVMET_MIN_POSTBUF 16 -#define LPFC_NVMET_DEFAULT_POSTBUF 1024 -#define LPFC_NVMET_MAX_POSTBUF 4096 #define LPFC_NVME_WQSIZE 256 #define LPFC_NVME_ERSP_LEN 0x20 -- 2.1.0
[lpfc 09/19] Fix Kconfig defines.
From: Dick Kennedy One of the idefs in the previous kconfig patch was not corrected. Also one alingment issue fixed. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_attr.c | 2 +- drivers/scsi/lpfc/lpfc_nvme.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 9e66cb0..0e28c2e 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -3335,7 +3335,7 @@ LPFC_ATTR_R(enable_fc4_type, LPFC_ENABLE_FCP, * percentage will go to NVME. */ LPFC_ATTR_R(xri_split, 50, 10, 90, -"Division of XRI resources between SCSI and NVME"); + "Division of XRI resources between SCSI and NVME"); /* # lpfc_log_verbose: Only turn this flag on if you are willing to risk being diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 9726c95..9d39093 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -2264,7 +2264,7 @@ lpfc_nvme_destroy_localport(struct lpfc_vport *vport) void lpfc_nvme_update_localport(struct lpfc_vport *vport) { -#ifdef CONFIG_LPFC_NVME_INITIATOR +#if (IS_ENABLED(CONFIG_NVME_FC)) struct nvme_fc_local_port *localport; struct lpfc_nvme_lport *lport; -- 2.1.0
[lpfc 03/19] Fix spelling in comments.
From: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_sli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 1c9fa45..7087c55 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -6338,7 +6338,7 @@ lpfc_sli4_get_allocated_extnts(struct lpfc_hba *phba, uint16_t type, } /** - * lpfc_sli4_repost_sgl_list - Repsot the buffers sgl pages as block + * lpfc_sli4_repost_sgl_list - Repost the buffers sgl pages as block * @phba: pointer to lpfc hba data structure. * @pring: Pointer to driver SLI ring object. * @sgl_list: linked link of sgl buffers to post -- 2.1.0
[lpfc 13/19] Fix driver load issues when MRQ=8
From: Dick Kennedy The symptom is that the driver will fail to login to the fabric. The reason is bacause it is out of iocb resources. This fix algins the number of MRQ resources with the total resources so that it can handle fabric events when needed. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_init.c | 2 +- drivers/scsi/lpfc/lpfc_nvme.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 88977b8..12c7e9a 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -10280,7 +10280,7 @@ lpfc_pci_probe_one_s3(struct pci_dev *pdev, const struct pci_device_id *pid) struct lpfc_hba *phba; struct lpfc_vport *vport = NULL; struct Scsi_Host *shost = NULL; - int error; + int error, cnt; uint32_t cfg_mode, intr_mode; /* Allocate memory for HBA structure */ diff --git a/drivers/scsi/lpfc/lpfc_nvme.c b/drivers/scsi/lpfc/lpfc_nvme.c index 9468679..5145ef2 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.c +++ b/drivers/scsi/lpfc/lpfc_nvme.c @@ -1480,6 +1480,7 @@ lpfc_nvme_fcp_abort(struct nvme_fc_local_port *pnvme_lport, phba->hba_flag); return; } + nvmereq_wqe = &lpfc_nbuf->cur_iocbq; lpfc_nbuf = (struct lpfc_nvme_buf *)pnvme_fcreq->private; if (!lpfc_nbuf) { -- 2.1.0
[lpfc 01/19] Fix advertised max_sgl_segment count for NVMET
From: Dick Kennedy Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_nvme.h | 4 +--- drivers/scsi/lpfc/lpfc_nvmet.c | 2 +- drivers/scsi/lpfc/lpfc_nvmet.h | 4 +--- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_nvme.h b/drivers/scsi/lpfc/lpfc_nvme.h index 1347deb..6277796 100644 --- a/drivers/scsi/lpfc/lpfc_nvme.h +++ b/drivers/scsi/lpfc/lpfc_nvme.h @@ -21,9 +21,7 @@ * included with this package. * / -#define LPFC_NVME_MIN_SEGS 16 -#define LPFC_NVME_DEFAULT_SEGS 66 /* 256K IOs - 64 + 2 */ -#define LPFC_NVME_MAX_SEGS 510 +#define LPFC_NVME_DEFAULT_SEGS (64 + 1)/* 256K IOs */ #define LPFC_NVMET_MIN_POSTBUF 16 #define LPFC_NVMET_DEFAULT_POSTBUF 1024 #define LPFC_NVMET_MAX_POSTBUF 4096 diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index 7ca868f..86ab95c 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c @@ -667,7 +667,7 @@ lpfc_nvmet_create_targetport(struct lpfc_hba *phba) pinfo.port_id = vport->fc_myDID; lpfc_tgttemplate.max_hw_queues = phba->cfg_nvme_io_channel; - lpfc_tgttemplate.max_sgl_segments = phba->cfg_sg_seg_cnt; + lpfc_tgttemplate.max_sgl_segments = phba->cfg_sg_seg_cnt + 1; lpfc_tgttemplate.target_features = NVMET_FCTGTFEAT_READDATA_RSP | NVMET_FCTGTFEAT_NEEDS_CMD_CPUSCHED; diff --git a/drivers/scsi/lpfc/lpfc_nvmet.h b/drivers/scsi/lpfc/lpfc_nvmet.h index ca96f05..0aa202c 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.h +++ b/drivers/scsi/lpfc/lpfc_nvmet.h @@ -21,9 +21,7 @@ * included with this package. * / -#define LPFC_NVMET_MIN_SEGS16 -#define LPFC_NVMET_DEFAULT_SEGS64 /* 256K IOs */ -#define LPFC_NVMET_MAX_SEGS510 +#define LPFC_NVMET_DEFAULT_SEGS(64 + 1)/* 256K IOs */ #define LPFC_NVMET_SUCCESS_LEN 12 /* Used for NVME Target */ -- 2.1.0
[lpfc 17/19] Fix implicit logo and RSCN handling for NVMET
From: Dick Kennedy Symptoms: NVMET didn't have any RSCN handling at all and would not execute implicit LOGO when receiving a PLOGI from an rport that NVMET had in state UNMAPPED. Clean up the logic in lpfc_nlp_state_cleanup for initiators (FCP and NVME). NVMET should not respond to RSCN including allocating new ndlps so this code was conditionalized when nvmet_support is true. The check for NLP_RCV_PLOGI in lpfc_setup_disc_node was moved below the check for nvmet_support to allow the NVMET to recover initiator nodes correctly. The implicit logo was introduced with lpfc_rcv_plogi when NVMET gets a PLOGI on an ndlp in UNMAPPED state. The RSCN handling was modified to not respond to an RSCN in NVMET. Instead NVMET sends a GID_FT and determines if an NVMEP_INITIATOR it has is UNMAPPED but no longer in the zone membership. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_ct.c| 68 +- drivers/scsi/lpfc/lpfc_disc.h | 1 + drivers/scsi/lpfc/lpfc_els.c | 23 ++--- drivers/scsi/lpfc/lpfc_hbadisc.c | 62 ++ drivers/scsi/lpfc/lpfc_nportdisc.c | 8 +++-- 5 files changed, 110 insertions(+), 52 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index d3e9af9..7e6a38f 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -537,19 +537,53 @@ lpfc_prep_node_fc4type(struct lpfc_vport *vport, uint32_t Did, uint8_t fc4_type) } } +static void +lpfc_ns_rsp_audit_did(struct lpfc_vport *vport, uint32_t Did, uint8_t fc4_type) +{ + struct lpfc_hba *phba = vport->phba; + struct lpfc_nodelist *ndlp = NULL; + struct Scsi_Host *shost = lpfc_shost_from_vport(vport); + + /* +* To conserve rpi's, filter out addresses for other +* vports on the same physical HBAs. +*/ + if (Did != vport->fc_myDID && + (!lpfc_find_vport_by_did(phba, Did) || +vport->cfg_peer_port_login)) { + if (!phba->nvmet_support) { + /* FCPI/NVMEI path. Process Did */ + lpfc_prep_node_fc4type(vport, Did, fc4_type); + } else { + /* NVMET path. NVMET only cares about NVMEI nodes. */ + list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) { + if (ndlp->nlp_type != NLP_NVME_INITIATOR || + ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) + continue; + spin_lock_irq(shost->host_lock); + if (ndlp->nlp_DID == Did) + ndlp->nlp_flag &= ~NLP_NVMET_RECOV; + else + ndlp->nlp_flag |= NLP_NVMET_RECOV; + spin_unlock_irq(shost->host_lock); + } + } + } +} + static int lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint8_t fc4_type, uint32_t Size) { - struct lpfc_hba *phba = vport->phba; struct lpfc_sli_ct_request *Response = (struct lpfc_sli_ct_request *) mp->virt; - struct lpfc_nodelist *ndlp = NULL; struct lpfc_dmabuf *mlast, *next_mp; uint32_t *ctptr = (uint32_t *) & Response->un.gid.PortType; uint32_t Did, CTentry; int Cnt; struct list_head head; + struct Scsi_Host *shost = lpfc_shost_from_vport(vport); + struct lpfc_nodelist *ndlp = NULL; lpfc_set_disctmo(vport); vport->num_disc_nodes = 0; @@ -574,19 +608,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint8_t fc4_type, /* Get next DID from NameServer List */ CTentry = *ctptr++; Did = ((be32_to_cpu(CTentry)) & Mask_DID); - - ndlp = NULL; - - /* -* Check for rscn processing or not -* To conserve rpi's, filter out addresses for other -* vports on the same physical HBAs. -*/ - if ((Did != vport->fc_myDID) && - ((lpfc_find_vport_by_did(phba, Did) == NULL) || -vport->cfg_peer_port_login)) - lpfc_prep_node_fc4type(vport, Did, fc4_type); - + lpfc_ns_rsp_audit_did(vport, Did, fc4_type); if (CTentry & (cpu_to_be32(SLI_CT_LAST_ENTRY))) goto nsout1; @@ -596,6 +618,22 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint8_t fc4_type, } +
[lpfc 10/19] Remove hba lock from NVMET isssue WQE
From: Dick Kennedy Unecessary lock is taken. ring lock should be sufficient Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_nvmet.c | 4 1 file changed, 4 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_nvmet.c b/drivers/scsi/lpfc/lpfc_nvmet.c index 86ab95c..551e81a 100644 --- a/drivers/scsi/lpfc/lpfc_nvmet.c +++ b/drivers/scsi/lpfc/lpfc_nvmet.c @@ -519,7 +519,6 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport, container_of(rsp, struct lpfc_nvmet_rcv_ctx, ctx.fcp_req); struct lpfc_hba *phba = ctxp->phba; struct lpfc_iocbq *nvmewqeq; - unsigned long iflags; int rc, id; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS @@ -594,10 +593,7 @@ lpfc_nvmet_xmt_fcp_op(struct nvmet_fc_target_port *tgtport, lpfc_nvmeio_data(phba, "NVMET FCP CMND: xri x%x op x%x len x%x\n", ctxp->oxid, rsp->op, rsp->rsplen); - /* For now we take hbalock */ - spin_lock_irqsave(&phba->hbalock, iflags); rc = lpfc_sli4_issue_wqe(phba, LPFC_FCP_RING, nvmewqeq); - spin_unlock_irqrestore(&phba->hbalock, iflags); if (rc == WQE_SUCCESS) { ctxp->flag |= LPFC_NVMET_IO_INP; #ifdef CONFIG_SCSI_LPFC_DEBUG_FS -- 2.1.0
[lpfc 14/19] Fix crash after issuing lip reset
From: Dick Kennedy When RPI is not available, driver sends WQE with invalid RPI value and hence rej ected by HBA. lpfc :82:00.3: 1:3154 BLS ABORT RSP failed, data: x3/xa0320008 and lpfc :82:00.3: 1:(71):2753 PLOGI failure DID:FA Status:x3/xa0240008 In this case, driver accesses rpi_ids array out of bounds. Fix: Check return value of lpfc_sli4_alloc_rpi(). Do not allocate lpfc_nodelist entry if RPI is not available. Notes: When RPI is not available, we will get discovery timeouts and command drops for some of the vports as seen below. 2017-03-22T11:26:50.632070+05:30 linux-dput kernel: [58101.904888] lpfc :0b: 00.2: 0:(106):0273 Unexpected discovery timeout, vport State x0 2017-03-22T11:26:50.632089+05:30 linux-dput kernel: [58101.904895] lpfc :0b: 00.2: 0:(106):0230 Unexpected timeout, hba link state x5 2017-03-22T11:27:25.024065+05:30 linux-dput kernel: [58136.281620] lpfc :0b: 00.2: 0:(21):0111 Dropping received ELS cmd Data: x0 xc90c55 x0 Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_bsg.c | 4 drivers/scsi/lpfc/lpfc_crtn.h| 2 +- drivers/scsi/lpfc/lpfc_els.c | 35 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 47 ++-- drivers/scsi/lpfc/lpfc_init.c| 20 - drivers/scsi/lpfc/lpfc_sli.c | 3 +-- drivers/scsi/lpfc/lpfc_vport.c | 3 +-- 7 files changed, 68 insertions(+), 46 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_bsg.c b/drivers/scsi/lpfc/lpfc_bsg.c index 18157d2..a1686c2 100644 --- a/drivers/scsi/lpfc/lpfc_bsg.c +++ b/drivers/scsi/lpfc/lpfc_bsg.c @@ -2486,6 +2486,10 @@ static int lpfcdiag_loop_self_reg(struct lpfc_hba *phba, uint16_t *rpi) mbox, *rpi); else { *rpi = lpfc_sli4_alloc_rpi(phba); + if (*rpi == LPFC_RPI_ALLOC_ERROR) { + mempool_free(mbox, phba->mbox_mem_pool); + return -EBUSY; + } status = lpfc_reg_rpi(phba, phba->pport->vpi, phba->pport->fc_myDID, (uint8_t *)&phba->pport->fc_sparam, diff --git a/drivers/scsi/lpfc/lpfc_crtn.h b/drivers/scsi/lpfc/lpfc_crtn.h index 54e6ac4..d859aff 100644 --- a/drivers/scsi/lpfc/lpfc_crtn.h +++ b/drivers/scsi/lpfc/lpfc_crtn.h @@ -99,7 +99,7 @@ void lpfc_issue_reg_vpi(struct lpfc_hba *, struct lpfc_vport *); int lpfc_check_sli_ndlp(struct lpfc_hba *, struct lpfc_sli_ring *, struct lpfc_iocbq *, struct lpfc_nodelist *); -void lpfc_nlp_init(struct lpfc_vport *, struct lpfc_nodelist *, uint32_t); +struct lpfc_nodelist *lpfc_nlp_init(struct lpfc_vport *, uint32_t); struct lpfc_nodelist *lpfc_nlp_get(struct lpfc_nodelist *); int lpfc_nlp_put(struct lpfc_nodelist *); int lpfc_nlp_not_used(struct lpfc_nodelist *ndlp); diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index d6e0f58..ffdcac0 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -895,10 +895,9 @@ lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, * Cannot find existing Fabric ndlp, so allocate a * new one */ - ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); + ndlp = lpfc_nlp_init(vport, PT2PT_RemoteID); if (!ndlp) goto fail; - lpfc_nlp_init(vport, ndlp, PT2PT_RemoteID); } else if (!NLP_CHK_NODE_ACT(ndlp)) { ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE); @@ -1364,7 +1363,6 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba) int lpfc_initial_flogi(struct lpfc_vport *vport) { - struct lpfc_hba *phba = vport->phba; struct lpfc_nodelist *ndlp; vport->port_state = LPFC_FLOGI; @@ -1374,10 +1372,9 @@ lpfc_initial_flogi(struct lpfc_vport *vport) ndlp = lpfc_findnode_did(vport, Fabric_DID); if (!ndlp) { /* Cannot find existing Fabric ndlp, so allocate a new one */ - ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL); + ndlp = lpfc_nlp_init(vport, Fabric_DID); if (!ndlp) return 0; - lpfc_nlp_init(vport, ndlp, Fabric_DID); /* Set the node type */ ndlp->nlp_type |= NLP_FABRIC; /* Put ndlp onto node list */ @@ -1418,17 +1415,15 @@ lpfc_initial_flogi(struct lpfc_vport *vport) int lpfc_initial_fdisc(struct lpfc_vport *vport) { - struct lpfc_hba *phba = vport->phba; struct lpfc_nodelist *ndlp; /* First look for the Fabric ndlp */ ndlp = lpfc_findnod
[lpfc 07/19] Fix driver usage of 128B WQEs when WQ_CREATE is V1.
From: Dick Kennedy Verify WQ_CREATE with 128B WQEs in V0 and V1. Code review of another bug showed the driver passing 128B WQEs and 8 pages in WQ CREATE and V0. Code inspection/instrumentation showed that the driver uses V0 in WQ_CREATE and if the caller passes queue->entry_size 128B, the driver sets the hdr_version to V1 so all is good. When I tested the V1 WQ_CREATE, the mailbox failed causing the driver to unload. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_sli.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index d606944..1519fdf 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -14741,6 +14741,9 @@ lpfc_wq_create(struct lpfc_hba *phba, struct lpfc_queue *wq, case LPFC_Q_CREATE_VERSION_1: bf_set(lpfc_mbx_wq_create_wqe_count, &wq_create->u.request_1, wq->entry_count); + bf_set(lpfc_mbox_hdr_version, &shdr->request, + LPFC_Q_CREATE_VERSION_1); + switch (wq->entry_size) { default: case 64: -- 2.1.0
[lpfc 05/19] Fix driver unload/reload operation.
From: Dick Kennedy Two issues: (1) driver could not be unloaded and reloaded without some Oops or Panic occurring. (2) The driver was panicking because of a corruption in the Memory Manager when the iocb list was getting allocated. Root cause for the memory corruption was a double free of the Work Queue ring pointer memory - Freed once in the lpfc_sli4_queue_free when the CQ was destroyed and again in lpfc_sli4_queue_free when the WQ was destroyed. While the linux memory manager protects against NULL pointers, it can't protect against stale pointer kfree calls. There are other fixes in this patch found during testing. While they are not a direct corruption cause, they should be fixed to ensure consistent unload/reload. Signed-off-by: Dick Kennedy Signed-off-by: James Smart --- drivers/scsi/lpfc/lpfc_init.c | 46 +++ drivers/scsi/lpfc/lpfc_sli.c | 7 ++- 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index b56da01..cca7f81 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -5815,6 +5815,12 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) INIT_LIST_HEAD(&phba->sli4_hba.lpfc_vfi_blk_list); INIT_LIST_HEAD(&phba->lpfc_vpi_blk_list); + /* Initialize mboxq lists. If the early init routines fail +* these lists need to be correctly initialized. +*/ + INIT_LIST_HEAD(&phba->sli.mboxq); + INIT_LIST_HEAD(&phba->sli.mboxq_cmpl); + /* initialize optic_state to 0xFF */ phba->sli4_hba.lnk_info.optic_state = 0xff; @@ -5880,6 +5886,7 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) "READ_NV, mbxStatus x%x\n", bf_get(lpfc_mqe_command, &mboxq->u.mqe), bf_get(lpfc_mqe_status, &mboxq->u.mqe)); + mempool_free(mboxq, phba->mbox_mem_pool); rc = -EIO; goto out_free_bsmbx; } @@ -7805,7 +7812,7 @@ lpfc_alloc_fcp_wq_cq(struct lpfc_hba *phba, int wqidx) /* Create Fast Path FCP WQs */ wqesize = (phba->fcp_embed_io) ? - LPFC_WQE128_SIZE : phba->sli4_hba.wq_esize; + LPFC_WQE128_SIZE : phba->sli4_hba.wq_esize; qdesc = lpfc_sli4_queue_alloc(phba, wqesize, phba->sli4_hba.wq_ecount); if (!qdesc) { lpfc_printf_log(phba, KERN_ERR, LOG_INIT, @@ -7836,7 +7843,7 @@ int lpfc_sli4_queue_create(struct lpfc_hba *phba) { struct lpfc_queue *qdesc; - int idx, io_channel, max; + int idx, io_channel; /* * Create HBA Record arrays. @@ -7997,15 +8004,6 @@ lpfc_sli4_queue_create(struct lpfc_hba *phba) if (lpfc_alloc_nvme_wq_cq(phba, idx)) goto out_error; - /* allocate MRQ CQs */ - max = phba->cfg_nvme_io_channel; - if (max < phba->cfg_nvmet_mrq) - max = phba->cfg_nvmet_mrq; - - for (idx = 0; idx < max; idx++) - if (lpfc_alloc_nvme_wq_cq(phba, idx)) - goto out_error; - if (phba->nvmet_support) { for (idx = 0; idx < phba->cfg_nvmet_mrq; idx++) { qdesc = lpfc_sli4_queue_alloc(phba, @@ -8227,11 +8225,11 @@ lpfc_sli4_queue_destroy(struct lpfc_hba *phba) /* Release FCP cqs */ lpfc_sli4_release_queues(&phba->sli4_hba.fcp_cq, - phba->cfg_fcp_io_channel); +phba->cfg_fcp_io_channel); /* Release FCP wqs */ lpfc_sli4_release_queues(&phba->sli4_hba.fcp_wq, - phba->cfg_fcp_io_channel); +phba->cfg_fcp_io_channel); /* Release FCP CQ mapping array */ lpfc_sli4_release_queue_map(&phba->sli4_hba.fcp_cq_map); @@ -8577,15 +8575,15 @@ lpfc_sli4_queue_setup(struct lpfc_hba *phba) lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "0528 %s not allocated\n", phba->sli4_hba.mbx_cq ? - "Mailbox WQ" : "Mailbox CQ"); + "Mailbox WQ" : "Mailbox CQ"); rc = -ENOMEM; goto out_destroy; } rc = lpfc_create_wq_cq(phba, phba->sli4_hba.hba_eq[0], - phba->sli4_hba.mbx_cq, - phba->sli4_hba.mbx_wq, - NULL, 0, LPFC_MBOX); + phba->