From 7e12fdac01e3be8fa57ab09f5a55c505d82b4654 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 17:54:03 +0000 Subject: [PATCH 01/56] qla2x00t-32gbit: Minimize diffs with the upstream code See also upstream commit 62e9dd177732 ("scsi: qla2xxx: Change in PUREX to handle FPIN ELS requests"). git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9247 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index d614f4ac5..7f09e71f7 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -6379,7 +6379,8 @@ dealloc: rsp_els, rsp_els_dma); } -void qla24xx_free_purex_item(struct purex_item *item) +void +qla24xx_free_purex_item(struct purex_item *item) { if (item == &item->vha->default_item) memset(&item->vha->default_item, 0, sizeof(struct purex_item)); From 93474d5f292138642e18c54a9dce9ce91904a035 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 17:59:51 +0000 Subject: [PATCH 02/56] qla2x00t-32gbit: Fix the return value A negative error code should be returned. Link: https://lore.kernel.org/r/20200829075746.19166-1-tian.xianting@h3c.com Acked-by: Nilesh Javali Signed-off-by: Xianting Tian Signed-off-by: Martin K. Petersen See also upstream commit e5f48ac42cc9 ("scsi: qla2xxx: Fix the return value"). git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9248 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 2 +- qla2x00t-32gbit/qla_init.c | 6 +++--- qla2x00t-32gbit/qla_target.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index 87709f057..a84b6d427 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -1652,7 +1652,7 @@ typedef struct { */ uint8_t firmware_options[2]; - uint16_t frame_payload_size; + __le16 frame_payload_size; __le16 max_iocb_allocation; __le16 execution_throttle; uint8_t retry_count; diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index eecde3244..fc5043904 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -4603,18 +4603,18 @@ qla2x00_nvram_config(scsi_qla_host_t *vha) nv->firmware_options[1] = BIT_7 | BIT_5; nv->add_firmware_options[0] = BIT_5; nv->add_firmware_options[1] = BIT_5 | BIT_4; - nv->frame_payload_size = 2048; + nv->frame_payload_size = cpu_to_le16(2048); nv->special_options[1] = BIT_7; } else if (IS_QLA2200(ha)) { nv->firmware_options[0] = BIT_2 | BIT_1; nv->firmware_options[1] = BIT_7 | BIT_5; nv->add_firmware_options[0] = BIT_5; nv->add_firmware_options[1] = BIT_5 | BIT_4; - nv->frame_payload_size = 1024; + nv->frame_payload_size = cpu_to_le16(1024); } else if (IS_QLA2100(ha)) { nv->firmware_options[0] = BIT_3 | BIT_1; nv->firmware_options[1] = BIT_5; - nv->frame_payload_size = 1024; + nv->frame_payload_size = cpu_to_le16(1024); } nv->max_iocb_allocation = cpu_to_le16(256); diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index 64038f206..f193ad62d 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -3828,7 +3828,7 @@ int qlt_abort_cmd(struct qla_tgt_cmd *cmd) */ ql_dbg(ql_dbg_tgt_mgt, vha, 0xf016, "multiple abort. %p\n", cmd); - return EIO; + return -EIO; } cmd->aborted = 1; cmd->trc_flags |= TRC_ABORT; From 9f3d3f4cad641657ef63827abf5c08c30b2228b9 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 19:08:48 +0000 Subject: [PATCH 03/56] qla2xxx-32gbit: Warn if done() or free() are called on an already freed srb Emit a warning when ->done or ->free are called on an already freed srb. There is a hidden use-after-free bug in the driver which corrupts the srb memory pool which originates from the cleanup callbacks. An extensive search didn't bring any lights on the real problem. The initial fix was to set both pointers to NULL and try to catch invalid accesses. But instead the memory corruption was gone and the driver didn't crash. Since not all calling places check for NULL pointer, add explicitly default handlers. With this we workaround the memory corruption and add a debug help. Link: https://lore.kernel.org/r/20200908081516.8561-2-dwagner@suse.de Reviewed-by: Martin Wilck Reviewed-by: Arun Easi Signed-off-by: Daniel Wagner Signed-off-by: Martin K. Petersen See also upstream commit c0014f94218ea3a312f6235febea0d626c5f2154. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9249 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 10 ++++++++++ qla2x00t-32gbit/qla_inline.h | 5 +++++ 2 files changed, 15 insertions(+) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index fc5043904..275809962 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -63,6 +63,16 @@ void qla2x00_sp_free(srb_t *sp) qla2x00_rel_sp(sp); } +void qla2xxx_rel_done_warning(srb_t *sp, int res) +{ + WARN_ONCE(1, "Calling done() of an already freed srb %p object\n", sp); +} + +void qla2xxx_rel_free_warning(srb_t *sp) +{ + WARN_ONCE(1, "Calling free() of an already freed srb %p object\n", sp); +} + /* Asynchronous Login/Logout Routines -------------------------------------- */ unsigned long diff --git a/qla2x00t-32gbit/qla_inline.h b/qla2x00t-32gbit/qla_inline.h index 80b9ef776..bdbae9e6a 100644 --- a/qla2x00t-32gbit/qla_inline.h +++ b/qla2x00t-32gbit/qla_inline.h @@ -215,10 +215,15 @@ qla2xxx_get_qpair_sp(scsi_qla_host_t *vha, struct qla_qpair *qpair, return sp; } +void qla2xxx_rel_done_warning(srb_t *sp, int res); +void qla2xxx_rel_free_warning(srb_t *sp); + static inline void qla2xxx_rel_qpair_sp(struct qla_qpair *qpair, srb_t *sp) { sp->qpair = NULL; + sp->done = qla2xxx_rel_done_warning; + sp->free = qla2xxx_rel_free_warning; mempool_free(sp, qpair->srb_mempool); QLA_QPAIR_MARK_NOT_BUSY(qpair); } From 6c052abd82c0e15c871fe5c131ca7ee687d3fc9c Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 19:09:41 +0000 Subject: [PATCH 04/56] qla2x00t-32gbit: Simplify return value logic in qla2x00_get_sp_from_handle() Refactor qla2x00_get_sp_from_handle() to avoid the unnecessary goto if early returns are used. With this we can also avoid preinitialzing the sp pointer. Link: https://lore.kernel.org/r/20200908081516.8561-3-dwagner@suse.de Reviewed-by: Martin Wilck Reviewed-by: Arun Easi Signed-off-by: Daniel Wagner Signed-off-by: Martin K. Petersen See also upstream commit 622299f16f33852baddf94b32bc80e2c1e24c39a. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9250 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_isr.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index 4323b97b0..5ef9c7ea4 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -1728,7 +1728,7 @@ qla2x00_get_sp_from_handle(scsi_qla_host_t *vha, const char *func, { struct qla_hw_data *ha = vha->hw; sts_entry_t *pkt = iocb; - srb_t *sp = NULL; + srb_t *sp; uint16_t index; index = LSW(pkt->handle); @@ -1740,13 +1740,13 @@ qla2x00_get_sp_from_handle(scsi_qla_host_t *vha, const char *func, set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags); else set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); - goto done; + return NULL; } sp = req->outstanding_cmds[index]; if (!sp) { ql_log(ql_log_warn, vha, 0x5032, "Invalid completion handle (%x) -- timed-out.\n", index); - return sp; + return NULL; } if (sp->handle != index) { ql_log(ql_log_warn, vha, 0x5033, @@ -1755,8 +1755,6 @@ qla2x00_get_sp_from_handle(scsi_qla_host_t *vha, const char *func, } req->outstanding_cmds[index] = NULL; - -done: return sp; } From 6fdda1cbc8af10057f79831c146d1217a8506d9b Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 19:10:35 +0000 Subject: [PATCH 05/56] qla2x00t-32gbit: Log calling function name in qla2x00_get_sp_from_handle() Commit 7c3df1320e5e ("[SCSI] qla2xxx: Code changes to support new dynamic logging infrastructure.") removed the use of the func argument. Let's add it back. Link: https://lore.kernel.org/r/20200908081516.8561-4-dwagner@suse.de Reviewed-by: Arun Easi Signed-off-by: Daniel Wagner Signed-off-by: Martin K. Petersen See also upstream commit 7d88d5dff95f929e94b9d6425f699eba22e47444. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9251 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_isr.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index 5ef9c7ea4..2ba115eab 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -1734,8 +1734,8 @@ qla2x00_get_sp_from_handle(scsi_qla_host_t *vha, const char *func, index = LSW(pkt->handle); if (index >= req->num_outstanding_cmds) { ql_log(ql_log_warn, vha, 0x5031, - "Invalid command index (%x) type %8ph.\n", - index, iocb); + "%s: Invalid command index (%x) type %8ph.\n", + func, index, iocb); if (IS_P3P_TYPE(ha)) set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags); else @@ -1745,12 +1745,14 @@ qla2x00_get_sp_from_handle(scsi_qla_host_t *vha, const char *func, sp = req->outstanding_cmds[index]; if (!sp) { ql_log(ql_log_warn, vha, 0x5032, - "Invalid completion handle (%x) -- timed-out.\n", index); + "%s: Invalid completion handle (%x) -- timed-out.\n", + func, index); return NULL; } if (sp->handle != index) { ql_log(ql_log_warn, vha, 0x5033, - "SRB handle (%x) mismatch %x.\n", sp->handle, index); + "%s: SRB handle (%x) mismatch %x.\n", func, + sp->handle, index); return NULL; } From 5d0620470c7b1feb09036336295e946e701eb9de Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 19:11:15 +0000 Subject: [PATCH 06/56] qla2x00t-32gbit: Handle incorrect entry_type entries It was observed on an ISP8324 16Gb HBA with fw=8.08.203 (d0d5) in a PowerPC64 machine that pkt->entry_type was MBX_IOCB_TYPE/0x39 with an sp->type SRB_SCSI_CMD which is invalid and should not be possible. Reading the entry_type from the crash dump shows the expected value of STATUS_TYPE/0x03 but the call trace shows that qla24xx_mbx_iocb_entry() is used. Add a check to verify for consistency and reset the HBA if an invalid state is reached. Obviously, this is only a workaround until the real problem is solved. Link: https://lore.kernel.org/r/20200908081516.8561-5-dwagner@suse.de Reviewed-by: Arun Easi Signed-off-by: Daniel Wagner Signed-off-by: Martin K. Petersen See also upstream commit 31a3271ff11badc50d6dc0efb4da393e4c3bf388. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9252 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_isr.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index 2ba115eab..7b59e9aa8 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -3441,6 +3441,32 @@ void qla24xx_nvme_ls4_iocb(struct scsi_qla_host *vha, sp->done(sp, comp_status); } +static void qla24xx_process_mbx_iocb_response(struct scsi_qla_host *vha, + struct rsp_que *rsp, struct sts_entry_24xx *pkt) +{ + struct qla_hw_data *ha = vha->hw; + srb_t *sp; + static const char func[] = "MBX-IOCB2"; + + sp = qla2x00_get_sp_from_handle(vha, func, rsp->req, pkt); + if (!sp) + return; + + if (sp->type == SRB_SCSI_CMD || + sp->type == SRB_NVME_CMD || + sp->type == SRB_TM_CMD) { + ql_log(ql_log_warn, vha, 0x509d, + "Inconsistent event entry type %d\n", sp->type); + if (IS_P3P_TYPE(ha)) + set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags); + else + set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); + return; + } + + qla24xx_mbx_iocb_entry(vha, rsp->req, (struct mbx_24xx_entry *)pkt); +} + /** * qla24xx_process_response_queue() - Process response queue entries. * @vha: SCSI driver HA context @@ -3548,8 +3574,7 @@ process_err: (struct abort_entry_24xx *)pkt); break; case MBX_IOCB_TYPE: - qla24xx_mbx_iocb_entry(vha, rsp->req, - (struct mbx_24xx_entry *)pkt); + qla24xx_process_mbx_iocb_response(vha, rsp, pkt); break; case VP_CTRL_IOCB_TYPE: qla_ctrlvp_completed(vha, rsp->req, From faccc547b8957bc0955281341766467bbed82e67 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 19:12:14 +0000 Subject: [PATCH 07/56] qla2x00t-32gbit: Remove unneeded variable 'rval' This addresses the following coccinelle warning: drivers/scsi/qla2xxx/qla_init.c:7112:5-9: Unneeded variable: "rval". Return "QLA_SUCCESS" on line 7115 Link: https://lore.kernel.org/r/20200911091021.2937708-1-yanaijie@huawei.com Reported-by: Hulk Robot Reviewed-by: Himanshu Madhani Signed-off-by: Jason Yan Signed-off-by: Martin K. Petersen See also upstream commit 34eb5ccf35daea082b6bc3857f82f23155fb266f. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9253 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 275809962..912a9d218 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -7119,10 +7119,9 @@ qla24xx_reset_adapter(scsi_qla_host_t *vha) unsigned long flags = 0; struct qla_hw_data *ha = vha->hw; struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; - int rval = QLA_SUCCESS; if (IS_P3P_TYPE(ha)) - return rval; + return QLA_SUCCESS; vha->flags.online = 0; ha->isp_ops->disable_intrs(ha); @@ -7137,7 +7136,7 @@ qla24xx_reset_adapter(scsi_qla_host_t *vha) if (IS_NOPOLLING_TYPE(ha)) ha->isp_ops->enable_intrs(ha); - return rval; + return QLA_SUCCESS; } /* On sparc systems, obtain port and node WWN from firmware From f7e687cf28ba570b1eb5f418213671c938cc21e9 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 19:14:28 +0000 Subject: [PATCH 08/56] qla2x00t-32gbit: Convert to SPDX license identifiers All files in this driver directory contain the following notice: See LICENSE.qla2xxx for copyright and licensing details. LICENSE.qla2xxx can be found in Documentation/scsi/. The file contains: - A copyright notice This copyright notice is redundant as all files contain the same copyright notice already - A license notice You may modify and redistribute the device driver code under the GNU General Public License (a copy of which is attached hereto as Exhibit A) published by the Free Software Foundation (version 2). This can be replaced with the corresponding SPDX license identifier (GPL-2.0-only) in the source files which reference this license file. - The full GPLv2 license text A redundant copy of LICENSES/preferred/GPL-2.0 Remove the notices and add the SPDX license identifier GPL-2.0-only to the source files. Finally remove the now redundant LICENSE.qla2xxx file. Reviewed-by: Richard Fontana Reviewed-by: Jilayne Lovejoy Reviewed-by: Alexios Zavras Acked-by: Igor Russkikh Signed-off-by: Thomas Gleixner Signed-off-by: Lukas Bulwahn Acked-by: Nilesh Javali Signed-off-by: Greg Kroah-Hartman See also upstream commit 77adf3f01bf7a48eb27a466ac4d14f410b80afc1. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9254 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_attr.c | 3 +-- qla2x00t-32gbit/qla_bsg.c | 3 +-- qla2x00t-32gbit/qla_bsg.h | 3 +-- qla2x00t-32gbit/qla_dbg.c | 3 +-- qla2x00t-32gbit/qla_dbg.h | 3 +-- qla2x00t-32gbit/qla_def.h | 3 +-- qla2x00t-32gbit/qla_dfs.c | 3 +-- qla2x00t-32gbit/qla_fw.h | 3 +-- qla2x00t-32gbit/qla_gbl.h | 3 +-- qla2x00t-32gbit/qla_gs.c | 3 +-- qla2x00t-32gbit/qla_init.c | 3 +-- qla2x00t-32gbit/qla_inline.h | 3 +-- qla2x00t-32gbit/qla_iocb.c | 3 +-- qla2x00t-32gbit/qla_isr.c | 3 +-- qla2x00t-32gbit/qla_mbx.c | 3 +-- qla2x00t-32gbit/qla_mid.c | 3 +-- qla2x00t-32gbit/qla_mr.c | 3 +-- qla2x00t-32gbit/qla_mr.h | 3 +-- qla2x00t-32gbit/qla_nvme.c | 3 +-- qla2x00t-32gbit/qla_nvme.h | 3 +-- qla2x00t-32gbit/qla_nx.c | 3 +-- qla2x00t-32gbit/qla_nx.h | 3 +-- qla2x00t-32gbit/qla_nx2.c | 3 +-- qla2x00t-32gbit/qla_nx2.h | 3 +-- qla2x00t-32gbit/qla_os.c | 3 +-- qla2x00t-32gbit/qla_settings.h | 3 +-- qla2x00t-32gbit/qla_sup.c | 3 +-- qla2x00t-32gbit/qla_tmpl.c | 3 +-- qla2x00t-32gbit/qla_tmpl.h | 3 +-- qla2x00t-32gbit/qla_version.h | 3 +-- 30 files changed, 30 insertions(+), 60 deletions(-) diff --git a/qla2x00t-32gbit/qla_attr.c b/qla2x00t-32gbit/qla_attr.c index 469f0ee50..4783b16d3 100644 --- a/qla2x00t-32gbit/qla_attr.c +++ b/qla2x00t-32gbit/qla_attr.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" #include "qla_target.h" diff --git a/qla2x00t-32gbit/qla_bsg.c b/qla2x00t-32gbit/qla_bsg.c index 9943d2dd8..0e4c53733 100644 --- a/qla2x00t-32gbit/qla_bsg.c +++ b/qla2x00t-32gbit/qla_bsg.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" diff --git a/qla2x00t-32gbit/qla_bsg.h b/qla2x00t-32gbit/qla_bsg.h index 7594fad7b..1a09b5512 100644 --- a/qla2x00t-32gbit/qla_bsg.h +++ b/qla2x00t-32gbit/qla_bsg.h @@ -1,8 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #ifndef __QLA_BSG_H #define __QLA_BSG_H diff --git a/qla2x00t-32gbit/qla_dbg.c b/qla2x00t-32gbit/qla_dbg.c index 1be811a5d..75a008512 100644 --- a/qla2x00t-32gbit/qla_dbg.c +++ b/qla2x00t-32gbit/qla_dbg.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ /* diff --git a/qla2x00t-32gbit/qla_dbg.h b/qla2x00t-32gbit/qla_dbg.h index e1d7de63e..2e59e75c6 100644 --- a/qla2x00t-32gbit/qla_dbg.h +++ b/qla2x00t-32gbit/qla_dbg.h @@ -1,8 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index a84b6d427..778c77d07 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -1,8 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #ifndef __QLA_DEF_H #define __QLA_DEF_H diff --git a/qla2x00t-32gbit/qla_dfs.c b/qla2x00t-32gbit/qla_dfs.c index e62b21152..1db2eded5 100644 --- a/qla2x00t-32gbit/qla_dfs.c +++ b/qla2x00t-32gbit/qla_dfs.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" diff --git a/qla2x00t-32gbit/qla_fw.h b/qla2x00t-32gbit/qla_fw.h index f2d560d50..c62e6100c 100644 --- a/qla2x00t-32gbit/qla_fw.h +++ b/qla2x00t-32gbit/qla_fw.h @@ -1,8 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #ifndef __QLA_FW_H #define __QLA_FW_H diff --git a/qla2x00t-32gbit/qla_gbl.h b/qla2x00t-32gbit/qla_gbl.h index 83470ec8f..365098776 100644 --- a/qla2x00t-32gbit/qla_gbl.h +++ b/qla2x00t-32gbit/qla_gbl.h @@ -1,8 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #ifndef __QLA_GBL_H #define __QLA_GBL_H diff --git a/qla2x00t-32gbit/qla_gs.c b/qla2x00t-32gbit/qla_gs.c index b569fd6e9..30fae605b 100644 --- a/qla2x00t-32gbit/qla_gs.c +++ b/qla2x00t-32gbit/qla_gs.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" #include "qla_target.h" diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 912a9d218..7f5307319 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" #include "qla_gbl.h" diff --git a/qla2x00t-32gbit/qla_inline.h b/qla2x00t-32gbit/qla_inline.h index bdbae9e6a..0512b6294 100644 --- a/qla2x00t-32gbit/qla_inline.h +++ b/qla2x00t-32gbit/qla_inline.h @@ -1,8 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #ifdef INSIDE_KERNEL_TREE diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index a2aa5b3be..00ecd5d51 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" #include "qla_target.h" diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index 7b59e9aa8..67db66d3f 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" #include "qla_target.h" diff --git a/qla2x00t-32gbit/qla_mbx.c b/qla2x00t-32gbit/qla_mbx.c index 53c732178..2f7697250 100644 --- a/qla2x00t-32gbit/qla_mbx.c +++ b/qla2x00t-32gbit/qla_mbx.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" #include "qla_target.h" diff --git a/qla2x00t-32gbit/qla_mid.c b/qla2x00t-32gbit/qla_mid.c index 15efe2f04..afa59b485 100644 --- a/qla2x00t-32gbit/qla_mid.c +++ b/qla2x00t-32gbit/qla_mid.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" #include "qla_gbl.h" diff --git a/qla2x00t-32gbit/qla_mr.c b/qla2x00t-32gbit/qla_mr.c index e2d854fdb..608e06777 100644 --- a/qla2x00t-32gbit/qla_mr.c +++ b/qla2x00t-32gbit/qla_mr.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" #include diff --git a/qla2x00t-32gbit/qla_mr.h b/qla2x00t-32gbit/qla_mr.h index 968fc760a..eefbae9d7 100644 --- a/qla2x00t-32gbit/qla_mr.h +++ b/qla2x00t-32gbit/qla_mr.h @@ -1,8 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #ifndef __QLA_MR_H #define __QLA_MR_H diff --git a/qla2x00t-32gbit/qla_nvme.c b/qla2x00t-32gbit/qla_nvme.c index a4a06e5bb..b64139107 100644 --- a/qla2x00t-32gbit/qla_nvme.c +++ b/qla2x00t-32gbit/qla_nvme.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2017 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #include diff --git a/qla2x00t-32gbit/qla_nvme.h b/qla2x00t-32gbit/qla_nvme.h index 01376c6bb..b01200fcd 100644 --- a/qla2x00t-32gbit/qla_nvme.h +++ b/qla2x00t-32gbit/qla_nvme.h @@ -1,8 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2017 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #ifndef __QLA_NVME_H #define __QLA_NVME_H diff --git a/qla2x00t-32gbit/qla_nx.c b/qla2x00t-32gbit/qla_nx.c index 0c9f94e4e..7e45a0b94 100644 --- a/qla2x00t-32gbit/qla_nx.c +++ b/qla2x00t-32gbit/qla_nx.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" #include diff --git a/qla2x00t-32gbit/qla_nx.h b/qla2x00t-32gbit/qla_nx.h index 93344a059..8567eaf1b 100644 --- a/qla2x00t-32gbit/qla_nx.h +++ b/qla2x00t-32gbit/qla_nx.h @@ -1,8 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #ifndef __QLA_NX_H #define __QLA_NX_H diff --git a/qla2x00t-32gbit/qla_nx2.c b/qla2x00t-32gbit/qla_nx2.c index 50e57603c..3a415b12d 100644 --- a/qla2x00t-32gbit/qla_nx2.c +++ b/qla2x00t-32gbit/qla_nx2.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #include diff --git a/qla2x00t-32gbit/qla_nx2.h b/qla2x00t-32gbit/qla_nx2.h index 8ba7c1db0..2fc902a9f 100644 --- a/qla2x00t-32gbit/qla_nx2.h +++ b/qla2x00t-32gbit/qla_nx2.h @@ -1,8 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #ifndef __QLA_NX2_H diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 7f09e71f7..c1121d4d4 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" diff --git a/qla2x00t-32gbit/qla_settings.h b/qla2x00t-32gbit/qla_settings.h index 2fb7ebfbb..a5f3000ae 100644 --- a/qla2x00t-32gbit/qla_settings.h +++ b/qla2x00t-32gbit/qla_settings.h @@ -1,8 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #define MAX_RETRIES_OF_ISP_ABORT 5 diff --git a/qla2x00t-32gbit/qla_sup.c b/qla2x00t-32gbit/qla_sup.c index 411b8a9ff..0f92e9a04 100644 --- a/qla2x00t-32gbit/qla_sup.c +++ b/qla2x00t-32gbit/qla_sup.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" diff --git a/qla2x00t-32gbit/qla_tmpl.c b/qla2x00t-32gbit/qla_tmpl.c index 8dc82cfd3..03fff32b5 100644 --- a/qla2x00t-32gbit/qla_tmpl.c +++ b/qla2x00t-32gbit/qla_tmpl.c @@ -1,8 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #include "qla_def.h" #include "qla_tmpl.h" diff --git a/qla2x00t-32gbit/qla_tmpl.h b/qla2x00t-32gbit/qla_tmpl.h index 89280b347..c47184db5 100644 --- a/qla2x00t-32gbit/qla_tmpl.h +++ b/qla2x00t-32gbit/qla_tmpl.h @@ -1,8 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ #ifndef __QLA_DMP27_H__ diff --git a/qla2x00t-32gbit/qla_version.h b/qla2x00t-32gbit/qla_version.h index 8ccd9ba1d..3ca1fb968 100644 --- a/qla2x00t-32gbit/qla_version.h +++ b/qla2x00t-32gbit/qla_version.h @@ -1,8 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ /* * QLogic Fibre Channel HBA Driver * Copyright (c) 2003-2014 QLogic Corporation - * - * See LICENSE.qla2xxx for copyright and licensing details. */ /* * Driver version From 3922313aa5b44ff08381e751f2c9acdf85de0ce0 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 19:17:45 +0000 Subject: [PATCH 09/56] qla2x00t-32gbit: Fix I/O failures during remote port toggle testing Driver was using a lower value for dev_loss_tmo making it more prone to I/O failures during remote port toggle testing. Set dev_loss_tmo to zero during remote port registration to allow nvme-fc default dev_loss_tmo to be used, which is higher than what driver was using. Link: https://lore.kernel.org/r/20200904045128.23631-2-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Himanshu Madhani Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit dd8d0bf6fb72bc73dc534d0d222e769e71d2202c. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9255 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_nvme.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/qla2x00t-32gbit/qla_nvme.h b/qla2x00t-32gbit/qla_nvme.h index b01200fcd..54a7e8d40 100644 --- a/qla2x00t-32gbit/qla_nvme.h +++ b/qla2x00t-32gbit/qla_nvme.h @@ -16,9 +16,6 @@ #include "qla_def.h" #include "qla_dsd.h" -/* default dev loss time (seconds) before transport tears down ctrl */ -#define NVME_FC_DEV_LOSS_TMO 30 - #define NVME_ATIO_CMD_OFF 32 #define NVME_FIRST_PACKET_CMDLEN (64 - NVME_ATIO_CMD_OFF) #define Q2T_NVME_NUM_TAGS 2048 From 6d60582dff2020d11feb9c19961b1e5e62e4caf3 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 19:20:08 +0000 Subject: [PATCH 10/56] qla2x00t-32gbit: Fix I/O failures during remote port toggle testing (part 2) git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9256 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_nvme.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_nvme.c b/qla2x00t-32gbit/qla_nvme.c index b64139107..1b4a26de5 100644 --- a/qla2x00t-32gbit/qla_nvme.c +++ b/qla2x00t-32gbit/qla_nvme.c @@ -49,9 +49,11 @@ int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport) #if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) /* * See also commit 9dd9686b1419 ("scsi: qla2xxx: Add changes for - * devloss timeout in driver") # v4.17. + * devloss timeout in driver") # v4.17. See also commit dd8d0bf6fb72 + * ("scsi: qla2xxx: Fix I/O failures during remote port toggle + * testing") # v5.10. */ - req.dev_loss_tmo = NVME_FC_DEV_LOSS_TMO; + req.dev_loss_tmo = 0; #endif if (fcport->nvme_prli_service_param & NVME_PRLI_SP_INITIATOR) From c121158a2a78b4015bbc8aa398a9aace2e1e7592 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 20:06:16 +0000 Subject: [PATCH 11/56] qla2x00t-32gbit: Setup debugfs entries for remote ports Create a base for adding remote port related entries in debugfs. Link: https://lore.kernel.org/r/20200904045128.23631-3-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Himanshu Madhani Signed-off-by: Saurav Kashyap Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit 1e98fb0f9208da058e2b6627f9f19fa0a95d05cd. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9257 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 4 ++++ qla2x00t-32gbit/qla_dfs.c | 42 +++++++++++++++++++++++++++++++++++- qla2x00t-32gbit/qla_gbl.h | 2 ++ qla2x00t-32gbit/qla_init.c | 2 ++ qla2x00t-32gbit/qla_target.c | 2 ++ 5 files changed, 51 insertions(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index 778c77d07..078df4526 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -2570,6 +2570,8 @@ typedef struct fc_port { u8 last_login_state; u16 n2n_link_reset_cnt; u16 n2n_chip_reset; + + struct dentry *dfs_rport_dir; } fc_port_t; enum { @@ -4806,6 +4808,8 @@ typedef struct scsi_qla_host { uint16_t ql2xexchoffld; uint16_t ql2xiniexchg; + struct dentry *dfs_rport_root; + struct purex_list { struct list_head head; spinlock_t lock; diff --git a/qla2x00t-32gbit/qla_dfs.c b/qla2x00t-32gbit/qla_dfs.c index 1db2eded5..7f3597ed8 100644 --- a/qla2x00t-32gbit/qla_dfs.c +++ b/qla2x00t-32gbit/qla_dfs.c @@ -11,6 +11,29 @@ static struct dentry *qla2x00_dfs_root; static atomic_t qla2x00_dfs_root_count; +void +qla2x00_dfs_create_rport(scsi_qla_host_t *vha, struct fc_port *fp) +{ + char wwn[32]; + + if (!vha->dfs_rport_root || fp->dfs_rport_dir) + return; + + sprintf(wwn, "pn-%016llx", wwn_to_u64(fp->port_name)); + fp->dfs_rport_dir = debugfs_create_dir(wwn, vha->dfs_rport_root); + if (!fp->dfs_rport_dir) + return; +} + +void +qla2x00_dfs_remove_rport(scsi_qla_host_t *vha, struct fc_port *fp) +{ + if (!vha->dfs_rport_root || !fp->dfs_rport_dir) + return; + debugfs_remove_recursive(fp->dfs_rport_dir); + fp->dfs_rport_dir = NULL; +} + static int qla2x00_dfs_tgt_sess_show(struct seq_file *s, void *unused) { @@ -472,9 +495,21 @@ create_nodes: ha->tgt.dfs_tgt_sess = debugfs_create_file("tgt_sess", S_IRUSR, ha->dfs_dir, vha, &dfs_tgt_sess_ops); - if (IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha)) + if (IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha)) { ha->tgt.dfs_naqp = debugfs_create_file("naqp", 0400, ha->dfs_dir, vha, &dfs_naqp_ops); + if (!ha->tgt.dfs_naqp) { + ql_log(ql_log_warn, vha, 0xd011, + "Unable to create debugFS naqp node.\n"); + goto out; + } + } + vha->dfs_rport_root = debugfs_create_dir("rports", ha->dfs_dir); + if (!vha->dfs_rport_root) { + ql_log(ql_log_warn, vha, 0xd012, + "Unable to create debugFS rports node.\n"); + goto out; + } out: return 0; } @@ -514,6 +549,11 @@ qla2x00_dfs_remove(scsi_qla_host_t *vha) ha->dfs_fce = NULL; } + if (vha->dfs_rport_root) { + debugfs_remove_recursive(vha->dfs_rport_root); + vha->dfs_rport_root = NULL; + } + if (ha->dfs_dir) { debugfs_remove(ha->dfs_dir); ha->dfs_dir = NULL; diff --git a/qla2x00t-32gbit/qla_gbl.h b/qla2x00t-32gbit/qla_gbl.h index 365098776..2b06bc665 100644 --- a/qla2x00t-32gbit/qla_gbl.h +++ b/qla2x00t-32gbit/qla_gbl.h @@ -943,6 +943,8 @@ void qlt_clr_qp_table(struct scsi_qla_host *vha); void qlt_set_mode(struct scsi_qla_host *); int qla2x00_set_data_rate(scsi_qla_host_t *vha, uint16_t mode); extern void qla24xx_process_purex_list(struct purex_list *); +extern void qla2x00_dfs_create_rport(scsi_qla_host_t *vha, struct fc_port *fp); +extern void qla2x00_dfs_remove_rport(scsi_qla_host_t *vha, struct fc_port *fp); /* nvme.c */ void qla_nvme_unregister_remote_port(struct fc_port *fcport); diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 7f5307319..67379d45d 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -5495,6 +5495,8 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) qla2x00_iidma_fcport(vha, fcport); + qla2x00_dfs_create_rport(vha, fcport); + if (NVME_TARGET(vha->hw, fcport)) { qla_nvme_register_remote(vha, fcport); qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE); diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index f193ad62d..21062e08c 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -1126,6 +1126,8 @@ void qlt_free_session_done(struct work_struct *work) spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); sess->free_pending = 0; + qla2x00_dfs_remove_rport(vha, sess); + ql_dbg(ql_dbg_disc, vha, 0xf001, "Unregistration of sess %p %8phC finished fcp_cnt %d\n", sess, sess->port_name, vha->fcport_count); From f48aaeb80069de093324262a5bb54d99a7584827 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 20:07:18 +0000 Subject: [PATCH 12/56] qla2x00t-32gbit: Allow dev_loss_tmo setting for FC-NVMe devices Add a remote port debugfs entry to get/set dev_loss_tmo for NVMe devices. Link: https://lore.kernel.org/r/20200904045128.23631-4-njavali@marvell.com Reported-by: kernel test robot Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Himanshu Madhani Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit 27c8aa5e1b069b7629e41bba83b522f99132a6b6. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9258 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_dfs.c | 58 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/qla2x00t-32gbit/qla_dfs.c b/qla2x00t-32gbit/qla_dfs.c index 7f3597ed8..beffb179f 100644 --- a/qla2x00t-32gbit/qla_dfs.c +++ b/qla2x00t-32gbit/qla_dfs.c @@ -11,6 +11,61 @@ static struct dentry *qla2x00_dfs_root; static atomic_t qla2x00_dfs_root_count; +#define QLA_DFS_RPORT_DEVLOSS_TMO 1 + +static int +qla_dfs_rport_get(struct fc_port *fp, int attr_id, u64 *val) +{ + switch (attr_id) { + case QLA_DFS_RPORT_DEVLOSS_TMO: + /* Only supported for FC-NVMe devices that are registered. */ + if (!(fp->nvme_flag & NVME_FLAG_REGISTERED)) + return -EIO; + *val = fp->nvme_remote_port->dev_loss_tmo; + break; + default: + return -EINVAL; + } + return 0; +} + +static int +qla_dfs_rport_set(struct fc_port *fp, int attr_id, u64 val) +{ + switch (attr_id) { + case QLA_DFS_RPORT_DEVLOSS_TMO: + /* Only supported for FC-NVMe devices that are registered. */ + if (!(fp->nvme_flag & NVME_FLAG_REGISTERED)) + return -EIO; +#if (IS_ENABLED(CONFIG_NVME_FC)) + return nvme_fc_set_remoteport_devloss(fp->nvme_remote_port, + val); +#else /* CONFIG_NVME_FC */ + return -EINVAL; +#endif /* CONFIG_NVME_FC */ + default: + return -EINVAL; + } + return 0; +} + +#define DEFINE_QLA_DFS_RPORT_RW_ATTR(_attr_id, _attr) \ +static int qla_dfs_rport_##_attr##_get(void *data, u64 *val) \ +{ \ + struct fc_port *fp = data; \ + return qla_dfs_rport_get(fp, _attr_id, val); \ +} \ +static int qla_dfs_rport_##_attr##_set(void *data, u64 val) \ +{ \ + struct fc_port *fp = data; \ + return qla_dfs_rport_set(fp, _attr_id, val); \ +} \ +DEFINE_DEBUGFS_ATTRIBUTE(qla_dfs_rport_##_attr##_fops, \ + qla_dfs_rport_##_attr##_get, \ + qla_dfs_rport_##_attr##_set, "%llu\n") + +DEFINE_QLA_DFS_RPORT_RW_ATTR(QLA_DFS_RPORT_DEVLOSS_TMO, dev_loss_tmo); + void qla2x00_dfs_create_rport(scsi_qla_host_t *vha, struct fc_port *fp) { @@ -23,6 +78,9 @@ qla2x00_dfs_create_rport(scsi_qla_host_t *vha, struct fc_port *fp) fp->dfs_rport_dir = debugfs_create_dir(wwn, vha->dfs_rport_root); if (!fp->dfs_rport_dir) return; + if (NVME_TARGET(vha->hw, fp)) + debugfs_create_file("dev_loss_tmo", 0600, fp->dfs_rport_dir, + fp, &qla_dfs_rport_dev_loss_tmo_fops); } void From fc2ae4183c091c9eecc5510be0aa83a6a577daf4 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 20:09:19 +0000 Subject: [PATCH 13/56] qla2x00t-32gbit: Honor status qualifier in FCP_RSP per spec FCP-4 (referred FCP-4 rev-2b) identifies the earlier known "retry delay timer" field as "status qualifier", which is described in SAM-5 and later specs. This fix makes appropriate driver side modifications to honor the new definition. The SAM document referred was SAM-6 rev-5. Link: https://lore.kernel.org/r/20200904045128.23631-5-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Himanshu Madhani Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit 3aac0c0fde17d2fdb65c7840bdf057a681f1e035. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9259 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_fw.h | 2 +- qla2x00t-32gbit/qla_inline.h | 38 ++++++++++++++++++++++++++++++++---- qla2x00t-32gbit/qla_isr.c | 18 +++++------------ 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/qla2x00t-32gbit/qla_fw.h b/qla2x00t-32gbit/qla_fw.h index c62e6100c..868ed5f70 100644 --- a/qla2x00t-32gbit/qla_fw.h +++ b/qla2x00t-32gbit/qla_fw.h @@ -630,7 +630,7 @@ struct sts_entry_24xx { #define SF_NVME_ERSP BIT_6 #define SF_FCP_RSP_DMA BIT_0 - __le16 retry_delay; + __le16 status_qualifier; __le16 scsi_status; /* SCSI status. */ #define SS_CONFIRMATION_REQ BIT_12 diff --git a/qla2x00t-32gbit/qla_inline.h b/qla2x00t-32gbit/qla_inline.h index 0512b6294..f7f13a6e4 100644 --- a/qla2x00t-32gbit/qla_inline.h +++ b/qla2x00t-32gbit/qla_inline.h @@ -278,11 +278,41 @@ qla2x00_handle_mbx_completion(struct qla_hw_data *ha, int status) } static inline void -qla2x00_set_retry_delay_timestamp(fc_port_t *fcport, uint16_t retry_delay) +qla2x00_set_retry_delay_timestamp(fc_port_t *fcport, uint16_t sts_qual) { - if (retry_delay) - fcport->retry_delay_timestamp = jiffies + - (retry_delay * HZ / 10); + u8 scope; + u16 qual; +#define SQ_SCOPE_MASK 0xc000 /* SAM-6 rev5 5.3.2 */ +#define SQ_SCOPE_SHIFT 14 +#define SQ_QUAL_MASK 0x3fff + +#define SQ_MAX_WAIT_SEC 60 /* Max I/O hold off time in seconds. */ +#define SQ_MAX_WAIT_TIME (SQ_MAX_WAIT_SEC * 10) /* in 100ms. */ + + if (!sts_qual) /* Common case. */ + return; + + scope = (sts_qual & SQ_SCOPE_MASK) >> SQ_SCOPE_SHIFT; + /* Handle only scope 1 or 2, which is for I-T nexus. */ + if (scope != 1 && scope != 2) + return; + + /* Skip processing, if retry delay timer is already in effect. */ + if (fcport->retry_delay_timestamp && + time_before(jiffies, fcport->retry_delay_timestamp)) + return; + + qual = sts_qual & SQ_QUAL_MASK; + if (qual < 1 || qual > 0x3fef) + return; + qual = min(qual, (u16)SQ_MAX_WAIT_TIME); + + /* qual is expressed in 100ms increments. */ + fcport->retry_delay_timestamp = jiffies + (qual * HZ / 10); + + ql_log(ql_log_warn, fcport->vha, 0x5101, + "%8phC: I/O throttling requested (status qualifier = %04xh), holding off I/Os for %ums.\n", + fcport->port_name, sts_qual, qual * 100); } static inline bool diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index 67db66d3f..123e4ec8a 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -2889,7 +2889,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) int logit = 1; int res = 0; uint16_t state_flags = 0; - uint16_t retry_delay = 0; + uint16_t sts_qual = 0; if (IS_FWI2_CAPABLE(ha)) { comp_status = le16_to_cpu(sts24->comp_status); @@ -2987,8 +2987,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) sense_len = par_sense_len = rsp_info_len = resid_len = fw_resid_len = 0; if (IS_FWI2_CAPABLE(ha)) { - u16 sts24_retry_delay = le16_to_cpu(sts24->retry_delay); - if (scsi_status & SS_SENSE_LEN_VALID) sense_len = le32_to_cpu(sts24->sense_len); if (scsi_status & SS_RESPONSE_INFO_LEN_VALID) @@ -3002,13 +3000,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) host_to_fcp_swap(sts24->data, sizeof(sts24->data)); ox_id = le16_to_cpu(sts24->ox_id); par_sense_len = sizeof(sts24->data); - /* Valid values of the retry delay timer are 0x1-0xffef */ - if (sts24_retry_delay > 0 && sts24_retry_delay < 0xfff1) { - retry_delay = sts24_retry_delay & 0x3fff; - ql_dbg(ql_dbg_io, sp->vha, 0x3033, - "%s: scope=%#x retry_delay=%#x\n", __func__, - sts24_retry_delay >> 14, retry_delay); - } + sts_qual = le16_to_cpu(sts24->status_qualifier); } else { if (scsi_status & SS_SENSE_LEN_VALID) sense_len = le16_to_cpu(sts->req_sense_length); @@ -3046,9 +3038,9 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) * Check retry_delay_timer value if we receive a busy or * queue full. */ - if (lscsi_status == SAM_STAT_TASK_SET_FULL || - lscsi_status == SAM_STAT_BUSY) - qla2x00_set_retry_delay_timestamp(fcport, retry_delay); + if (unlikely(lscsi_status == SAM_STAT_TASK_SET_FULL || + lscsi_status == SAM_STAT_BUSY)) + qla2x00_set_retry_delay_timestamp(fcport, sts_qual); /* * Based on Host and scsi status generate status code for Linux From 9887b73dd20d451cad998160adbbcf1e8b807bc1 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 20:10:28 +0000 Subject: [PATCH 14/56] qla2x00t-32gbit: Reduce duplicate code in reporting speed Indicate correct speed for 16G Mezz card. Link: https://lore.kernel.org/r/20200904045128.23631-6-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit d68930bae477e864e016aeb8d557f099b4636aac. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9260 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_attr.c | 41 +--------------- qla2x00t-32gbit/qla_gbl.h | 2 + qla2x00t-32gbit/qla_gs.c | 7 +-- qla2x00t-32gbit/qla_os.c | 96 +------------------------------------- 4 files changed, 9 insertions(+), 137 deletions(-) diff --git a/qla2x00t-32gbit/qla_attr.c b/qla2x00t-32gbit/qla_attr.c index 4783b16d3..53930294b 100644 --- a/qla2x00t-32gbit/qla_attr.c +++ b/qla2x00t-32gbit/qla_attr.c @@ -3216,46 +3216,7 @@ qla2x00_init_host_attr(scsi_qla_host_t *vha) fc_host_max_npiv_vports(vha->host) = ha->max_npiv_vports; fc_host_npiv_vports_inuse(vha->host) = ha->cur_vport_count; - if (IS_CNA_CAPABLE(ha)) - speeds = FC_PORTSPEED_10GBIT; - else if (IS_QLA28XX(ha) || IS_QLA27XX(ha)) { - if (ha->max_supported_speed == 2) { - if (ha->min_supported_speed <= 6) - speeds |= FC_PORTSPEED_64GBIT; - } - if (ha->max_supported_speed == 2 || - ha->max_supported_speed == 1) { - if (ha->min_supported_speed <= 5) - speeds |= FC_PORTSPEED_32GBIT; - } - if (ha->max_supported_speed == 2 || - ha->max_supported_speed == 1 || - ha->max_supported_speed == 0) { - if (ha->min_supported_speed <= 4) - speeds |= FC_PORTSPEED_16GBIT; - } - if (ha->max_supported_speed == 1 || - ha->max_supported_speed == 0) { - if (ha->min_supported_speed <= 3) - speeds |= FC_PORTSPEED_8GBIT; - } - if (ha->max_supported_speed == 0) { - if (ha->min_supported_speed <= 2) - speeds |= FC_PORTSPEED_4GBIT; - } - } else if (IS_QLA2031(ha)) - speeds = FC_PORTSPEED_16GBIT|FC_PORTSPEED_8GBIT| - FC_PORTSPEED_4GBIT; - else if (IS_QLA25XX(ha) || IS_QLAFX00(ha)) - speeds = FC_PORTSPEED_8GBIT|FC_PORTSPEED_4GBIT| - FC_PORTSPEED_2GBIT|FC_PORTSPEED_1GBIT; - else if (IS_QLA24XX_TYPE(ha)) - speeds = FC_PORTSPEED_4GBIT|FC_PORTSPEED_2GBIT| - FC_PORTSPEED_1GBIT; - else if (IS_QLA23XX(ha)) - speeds = FC_PORTSPEED_2GBIT|FC_PORTSPEED_1GBIT; - else - speeds = FC_PORTSPEED_1GBIT; + speeds = qla25xx_fdmi_port_speed_capability(ha); fc_host_supported_speeds(vha->host) = speeds; } diff --git a/qla2x00t-32gbit/qla_gbl.h b/qla2x00t-32gbit/qla_gbl.h index 2b06bc665..94941fd30 100644 --- a/qla2x00t-32gbit/qla_gbl.h +++ b/qla2x00t-32gbit/qla_gbl.h @@ -707,6 +707,8 @@ int qla24xx_async_gfpnid(scsi_qla_host_t *, fc_port_t *); void qla24xx_handle_gfpnid_event(scsi_qla_host_t *, struct event_arg *); void qla24xx_sp_unmap(scsi_qla_host_t *, srb_t *); void qla_scan_work_fn(struct work_struct *); +uint qla25xx_fdmi_port_speed_capability(struct qla_hw_data *); +uint qla25xx_fdmi_port_speed_currently(struct qla_hw_data *); /* * Global Function Prototypes in qla_attr.c source file. diff --git a/qla2x00t-32gbit/qla_gs.c b/qla2x00t-32gbit/qla_gs.c index 30fae605b..e28c4b7ec 100644 --- a/qla2x00t-32gbit/qla_gs.c +++ b/qla2x00t-32gbit/qla_gs.c @@ -1501,7 +1501,7 @@ qla2x00_prep_ct_fdmi_req(struct ct_sns_pkt *p, uint16_t cmd, return &p->p.req; } -static uint +uint qla25xx_fdmi_port_speed_capability(struct qla_hw_data *ha) { uint speeds = 0; @@ -1545,7 +1545,7 @@ qla25xx_fdmi_port_speed_capability(struct qla_hw_data *ha) } return speeds; } - if (IS_QLA25XX(ha)) + if (IS_QLA25XX(ha) || IS_QLAFX00(ha)) return FDMI_PORT_SPEED_8GB|FDMI_PORT_SPEED_4GB| FDMI_PORT_SPEED_2GB|FDMI_PORT_SPEED_1GB; if (IS_QLA24XX_TYPE(ha)) @@ -1555,7 +1555,8 @@ qla25xx_fdmi_port_speed_capability(struct qla_hw_data *ha) return FDMI_PORT_SPEED_2GB|FDMI_PORT_SPEED_1GB; return FDMI_PORT_SPEED_1GB; } -static uint + +uint qla25xx_fdmi_port_speed_currently(struct qla_hw_data *ha) { switch (ha->link_data_rate) { diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index c1121d4d4..e67c35a19 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -5861,98 +5861,6 @@ qla25xx_rdp_rsp_reduce_size(struct scsi_qla_host *vha, return true; } -static uint -qla25xx_rdp_port_speed_capability(struct qla_hw_data *ha) -{ - if (IS_CNA_CAPABLE(ha)) - return RDP_PORT_SPEED_10GB; - - if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { - unsigned int speeds = 0; - - if (ha->max_supported_speed == 2) { - if (ha->min_supported_speed <= 6) - speeds |= RDP_PORT_SPEED_64GB; - } - - if (ha->max_supported_speed == 2 || - ha->max_supported_speed == 1) { - if (ha->min_supported_speed <= 5) - speeds |= RDP_PORT_SPEED_32GB; - } - - if (ha->max_supported_speed == 2 || - ha->max_supported_speed == 1 || - ha->max_supported_speed == 0) { - if (ha->min_supported_speed <= 4) - speeds |= RDP_PORT_SPEED_16GB; - } - - if (ha->max_supported_speed == 1 || - ha->max_supported_speed == 0) { - if (ha->min_supported_speed <= 3) - speeds |= RDP_PORT_SPEED_8GB; - } - - if (ha->max_supported_speed == 0) { - if (ha->min_supported_speed <= 2) - speeds |= RDP_PORT_SPEED_4GB; - } - - return speeds; - } - - if (IS_QLA2031(ha)) - return RDP_PORT_SPEED_16GB|RDP_PORT_SPEED_8GB| - RDP_PORT_SPEED_4GB; - - if (IS_QLA25XX(ha)) - return RDP_PORT_SPEED_8GB|RDP_PORT_SPEED_4GB| - RDP_PORT_SPEED_2GB|RDP_PORT_SPEED_1GB; - - if (IS_QLA24XX_TYPE(ha)) - return RDP_PORT_SPEED_4GB|RDP_PORT_SPEED_2GB| - RDP_PORT_SPEED_1GB; - - if (IS_QLA23XX(ha)) - return RDP_PORT_SPEED_2GB|RDP_PORT_SPEED_1GB; - - return RDP_PORT_SPEED_1GB; -} - -static uint -qla25xx_rdp_port_speed_currently(struct qla_hw_data *ha) -{ - switch (ha->link_data_rate) { - case PORT_SPEED_1GB: - return RDP_PORT_SPEED_1GB; - - case PORT_SPEED_2GB: - return RDP_PORT_SPEED_2GB; - - case PORT_SPEED_4GB: - return RDP_PORT_SPEED_4GB; - - case PORT_SPEED_8GB: - return RDP_PORT_SPEED_8GB; - - case PORT_SPEED_10GB: - return RDP_PORT_SPEED_10GB; - - case PORT_SPEED_16GB: - return RDP_PORT_SPEED_16GB; - - case PORT_SPEED_32GB: - return RDP_PORT_SPEED_32GB; - - case PORT_SPEED_64GB: - return RDP_PORT_SPEED_64GB; - - default: - return RDP_PORT_SPEED_UNKNOWN; - } -} - /* * Function Name: qla24xx_process_purex_iocb * @@ -6119,9 +6027,9 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, rsp_payload->port_speed_desc.desc_len = cpu_to_be32(RDP_DESC_LEN(rsp_payload->port_speed_desc)); rsp_payload->port_speed_desc.speed_capab = cpu_to_be16( - qla25xx_rdp_port_speed_capability(ha)); + qla25xx_fdmi_port_speed_capability(ha)); rsp_payload->port_speed_desc.operating_speed = cpu_to_be16( - qla25xx_rdp_port_speed_currently(ha)); + qla25xx_fdmi_port_speed_currently(ha)); /* Link Error Status Descriptor */ rsp_payload->ls_err_desc.desc_tag = cpu_to_be32(0x10002); From 4aa1dc12c8d077290615437453d555aaf8387d52 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 22:48:59 +0000 Subject: [PATCH 15/56] qla2x00t-32gbit: Fix memory size truncation Memory size calculations for Extended Login used in hardware offload got truncated. Fix this by changing definition of exlogin_size to use uint32_t. Link: https://lore.kernel.org/r/20200904045128.23631-7-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit d38cb849e17a34637b97ce57c550ec70d63dd39a. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9261 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 2 +- qla2x00t-32gbit/qla_mbx.c | 7 ++++--- qla2x00t-32gbit/qla_os.c | 5 +++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index 078df4526..cd7ab5bc9 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -4242,7 +4242,7 @@ struct qla_hw_data { /* Extended Logins */ void *exlogin_buf; dma_addr_t exlogin_buf_dma; - int exlogin_size; + uint32_t exlogin_size; #define ENABLE_EXCHANGE_OFFLD BIT_2 diff --git a/qla2x00t-32gbit/qla_mbx.c b/qla2x00t-32gbit/qla_mbx.c index 2f7697250..0dff8e165 100644 --- a/qla2x00t-32gbit/qla_mbx.c +++ b/qla2x00t-32gbit/qla_mbx.c @@ -844,7 +844,7 @@ qla_get_exlogin_status(scsi_qla_host_t *vha, uint16_t *buf_sz, * Context: * Kernel context. */ -#define CONFIG_XLOGINS_MEM 0x3 +#define CONFIG_XLOGINS_MEM 0x9 int qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr) { @@ -871,8 +871,9 @@ qla_set_exlogin_mem_cfg(scsi_qla_host_t *vha, dma_addr_t phys_addr) mcp->flags = 0; rval = qla2x00_mailbox_command(vha, mcp); if (rval != QLA_SUCCESS) { - /*EMPTY*/ - ql_dbg(ql_dbg_mbx, vha, 0x111b, "Failed=%x.\n", rval); + ql_dbg(ql_dbg_mbx, vha, 0x111b, + "EXlogin Failed=%x. MB0=%x MB11=%x\n", + rval, mcp->mb[0], mcp->mb[11]); } else { ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118c, "Done %s.\n", __func__); diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index e67c35a19..112299b38 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -4426,11 +4426,12 @@ int qla2x00_set_exlogins_buffer(scsi_qla_host_t *vha) { int rval; - uint16_t size, max_cnt, temp; + uint16_t size, max_cnt; + uint32_t temp; struct qla_hw_data *ha = vha->hw; /* Return if we don't need to alloacate any extended logins */ - if (!ql2xexlogins) + if (ql2xexlogins <= MAX_FIBRE_DEVICES_2400) return QLA_SUCCESS; if (!IS_EXLOGIN_OFFLD_CAPABLE(ha)) From 3eb6d581ba171a2e538eb889cc1f8221dcab8f6f Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 22:52:11 +0000 Subject: [PATCH 16/56] qla2x00t-32gbit: Performance tweak Move statistics fields from vha struct to qpair to reduce memory thrashing. Link: https://lore.kernel.org/r/20200904045128.23631-8-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit 49db4d4e02aabcd4fa2f60142ef42e50fb2dd526. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9262 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_attr.c | 46 +++++++++++++++++++++++++++++++++----- qla2x00t-32gbit/qla_def.h | 33 ++++++++++++++++++++------- qla2x00t-32gbit/qla_init.c | 4 +--- qla2x00t-32gbit/qla_iocb.c | 18 ++++++++------- qla2x00t-32gbit/qla_isr.c | 9 +++++--- qla2x00t-32gbit/qla_mid.c | 4 +--- qla2x00t-32gbit/qla_nvme.c | 8 +++---- qla2x00t-32gbit/qla_os.c | 9 ++++---- 8 files changed, 92 insertions(+), 39 deletions(-) diff --git a/qla2x00t-32gbit/qla_attr.c b/qla2x00t-32gbit/qla_attr.c index 53930294b..c0c89ef3f 100644 --- a/qla2x00t-32gbit/qla_attr.c +++ b/qla2x00t-32gbit/qla_attr.c @@ -2725,6 +2725,9 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) struct link_statistics *stats; dma_addr_t stats_dma; struct fc_host_statistics *p = &vha->fc_host_stat; + struct qla_qpair *qpair; + int i; + u64 ib = 0, ob = 0, ir = 0, or = 0; memset(p, -1, sizeof(*p)); @@ -2761,6 +2764,27 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) if (rval != QLA_SUCCESS) goto done_free; + /* --- */ + for (i = 0; i < vha->hw->max_qpairs; i++) { + qpair = vha->hw->queue_pair_map[i]; + if (!qpair) + continue; + ir += qpair->counters.input_requests; + or += qpair->counters.output_requests; + ib += qpair->counters.input_bytes; + ob += qpair->counters.output_bytes; + } + ir += ha->base_qpair->counters.input_requests; + or += ha->base_qpair->counters.output_requests; + ib += ha->base_qpair->counters.input_bytes; + ob += ha->base_qpair->counters.output_bytes; + + ir += vha->qla_stats.input_requests; + or += vha->qla_stats.output_requests; + ib += vha->qla_stats.input_bytes; + ob += vha->qla_stats.output_bytes; + /* --- */ + p->link_failure_count = le32_to_cpu(stats->link_fail_cnt); p->loss_of_sync_count = le32_to_cpu(stats->loss_sync_cnt); p->loss_of_signal_count = le32_to_cpu(stats->loss_sig_cnt); @@ -2780,15 +2804,16 @@ qla2x00_get_fc_host_stats(struct Scsi_Host *shost) p->rx_words = le64_to_cpu(stats->fpm_recv_word_cnt); p->tx_words = le64_to_cpu(stats->fpm_xmit_word_cnt); } else { - p->rx_words = vha->qla_stats.input_bytes; - p->tx_words = vha->qla_stats.output_bytes; + p->rx_words = ib >> 2; + p->tx_words = ob >> 2; } } + p->fcp_control_requests = vha->qla_stats.control_requests; - p->fcp_input_requests = vha->qla_stats.input_requests; - p->fcp_output_requests = vha->qla_stats.output_requests; - p->fcp_input_megabytes = vha->qla_stats.input_bytes >> 20; - p->fcp_output_megabytes = vha->qla_stats.output_bytes >> 20; + p->fcp_input_requests = ir; + p->fcp_output_requests = or; + p->fcp_input_megabytes = ib >> 20; + p->fcp_output_megabytes = ob >> 20; p->seconds_since_last_reset = get_jiffies_64() - vha->qla_stats.jiffies_at_last_reset; do_div(p->seconds_since_last_reset, HZ); @@ -2808,9 +2833,18 @@ qla2x00_reset_host_stats(struct Scsi_Host *shost) struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); struct link_statistics *stats; dma_addr_t stats_dma; + int i; + struct qla_qpair *qpair; memset(&vha->qla_stats, 0, sizeof(vha->qla_stats)); memset(&vha->fc_host_stat, 0, sizeof(vha->fc_host_stat)); + for (i = 0; i < vha->hw->max_qpairs; i++) { + qpair = vha->hw->queue_pair_map[i]; + if (!qpair) + continue; + memset(&qpair->counters, 0, sizeof(qpair->counters)); + } + memset(&ha->base_qpair->counters, 0, sizeof(qpair->counters)); vha->qla_stats.jiffies_at_last_reset = get_jiffies_64(); diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index cd7ab5bc9..5b5decc3b 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -2468,12 +2468,6 @@ typedef struct fc_port { struct list_head list; struct scsi_qla_host *vha; - uint8_t node_name[WWN_SIZE]; - uint8_t port_name[WWN_SIZE]; - port_id_t d_id; - uint16_t loop_id; - uint16_t old_loop_id; - unsigned int conf_compl_supported:1; unsigned int deleted:2; unsigned int free_pending:1; @@ -2490,6 +2484,13 @@ typedef struct fc_port { unsigned int n2n_flag:1; unsigned int explicit_logout:1; unsigned int prli_pend_timer:1; + uint8_t nvme_flag; + + uint8_t node_name[WWN_SIZE]; + uint8_t port_name[WWN_SIZE]; + port_id_t d_id; + uint16_t loop_id; + uint16_t old_loop_id; struct completion nvme_del_done; uint32_t nvme_prli_service_param; @@ -2498,7 +2499,7 @@ typedef struct fc_port { #define NVME_PRLI_SP_TARGET BIT_4 #define NVME_PRLI_SP_DISCOVERY BIT_3 #define NVME_PRLI_SP_FIRST_BURST BIT_0 - uint8_t nvme_flag; + uint32_t nvme_first_burst_size; #define NVME_FLAG_REGISTERED 4 #define NVME_FLAG_DELETING 2 @@ -3536,6 +3537,14 @@ struct qla_tgt_counters { uint64_t num_term_xchg_sent; }; +struct qla_counters { + uint64_t input_bytes; + uint64_t input_requests; + uint64_t output_bytes; + uint64_t output_requests; + +}; + struct qla_qpair; /* Response queue data structure */ @@ -3620,6 +3629,7 @@ struct qla_qpair { uint32_t enable_class_2:1; uint32_t enable_explicit_conf:1; uint32_t use_shadow_reg:1; + uint32_t rcv_intr:1; uint16_t id; /* qp number used with FW */ uint16_t vp_idx; /* vport ID */ @@ -3635,13 +3645,16 @@ struct qla_qpair { struct qla_msix_entry *msix; /* point to &ha->msix_entries[x] */ struct qla_hw_data *hw; struct work_struct q_work; + struct qla_counters counters; + struct list_head qp_list_elem; /* vha->qp_list */ struct list_head hints_list; - uint16_t cpuid; + uint16_t retry_term_cnt; __le32 retry_term_exchg_addr; uint64_t retry_term_jiff; struct qla_tgt_counters tgt_counters; + uint16_t cpuid; }; /* Place holder for FW buffer parameters */ @@ -4155,6 +4168,10 @@ struct qla_hw_data { #define USE_ASYNC_SCAN(ha) (IS_QLA25XX(ha) || IS_QLA81XX(ha) ||\ IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) +#define IS_ZIO_THRESHOLD_CAPABLE(ha) \ + ((IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) &&\ + (ha->zio_mode == QLA_ZIO_MODE_6)) + /* HBA serial number */ uint8_t serial0; uint8_t serial1; diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 67379d45d..a4ff8e5a3 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -3699,9 +3699,7 @@ execute_fw_with_lr: goto execute_fw_with_lr; } - if ((IS_QLA83XX(ha) || IS_QLA27XX(ha) || - IS_QLA28XX(ha)) && - (ha->zio_mode == QLA_ZIO_MODE_6)) + if (IS_ZIO_THRESHOLD_CAPABLE(ha)) qla27xx_set_zio_threshold(vha, ha->last_zio_threshold); diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index 00ecd5d51..2b59c18dd 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -593,6 +593,7 @@ qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt, uint32_t dsd_list_len; struct dsd_dma *dsd_ptr; struct ct6_dsd *ctx; + struct qla_qpair *qpair = sp->qpair; cmd = GET_CMD_SP(sp); @@ -611,12 +612,12 @@ qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt, /* Set transfer direction */ if (cmd->sc_data_direction == DMA_TO_DEVICE) { cmd_pkt->control_flags = cpu_to_le16(CF_WRITE_DATA); - vha->qla_stats.output_bytes += scsi_bufflen(cmd); - vha->qla_stats.output_requests++; + qpair->counters.output_bytes += scsi_bufflen(cmd); + qpair->counters.output_requests++; } else if (cmd->sc_data_direction == DMA_FROM_DEVICE) { cmd_pkt->control_flags = cpu_to_le16(CF_READ_DATA); - vha->qla_stats.input_bytes += scsi_bufflen(cmd); - vha->qla_stats.input_requests++; + qpair->counters.input_bytes += scsi_bufflen(cmd); + qpair->counters.input_requests++; } cur_seg = scsi_sglist(cmd); @@ -703,6 +704,7 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt, struct scsi_cmnd *cmd; struct scatterlist *sg; int i; + struct qla_qpair *qpair = sp->qpair; cmd = GET_CMD_SP(sp); @@ -720,12 +722,12 @@ qla24xx_build_scsi_iocbs(srb_t *sp, struct cmd_type_7 *cmd_pkt, /* Set transfer direction */ if (cmd->sc_data_direction == DMA_TO_DEVICE) { cmd_pkt->task_mgmt_flags = cpu_to_le16(TMF_WRITE_DATA); - vha->qla_stats.output_bytes += scsi_bufflen(cmd); - vha->qla_stats.output_requests++; + qpair->counters.output_bytes += scsi_bufflen(cmd); + qpair->counters.output_requests++; } else if (cmd->sc_data_direction == DMA_FROM_DEVICE) { cmd_pkt->task_mgmt_flags = cpu_to_le16(TMF_READ_DATA); - vha->qla_stats.input_bytes += scsi_bufflen(cmd); - vha->qla_stats.input_requests++; + qpair->counters.input_bytes += scsi_bufflen(cmd); + qpair->counters.input_requests++; } /* One DSD is available in the Command Type 3 IOCB */ diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index 123e4ec8a..1d5c62635 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -3474,8 +3474,11 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, if (!ha->flags.fw_started) return; - if (rsp->qpair->cpuid != raw_smp_processor_id()) + if (rsp->qpair->cpuid != raw_smp_processor_id() || + !rsp->qpair->rcv_intr) { + rsp->qpair->rcv_intr = 1; qla_cpu_update(rsp->qpair, raw_smp_processor_id()); + } while (rsp->ring_ptr->signature != RESPONSE_PROCESSED) { pkt = (struct sts_entry_24xx *)rsp->ring_ptr; @@ -3924,7 +3927,7 @@ qla2xxx_msix_rsp_q(int irq, void *dev_id) } ha = qpair->hw; - queue_work(ha->wq, &qpair->q_work); + queue_work_on(smp_processor_id(), ha->wq, &qpair->q_work); return IRQ_HANDLED; } @@ -3950,7 +3953,7 @@ qla2xxx_msix_rsp_q_hs(int irq, void *dev_id) wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_INT); spin_unlock_irqrestore(&ha->hardware_lock, flags); - queue_work(ha->wq, &qpair->q_work); + queue_work_on(smp_processor_id(), ha->wq, &qpair->q_work); return IRQ_HANDLED; } diff --git a/qla2x00t-32gbit/qla_mid.c b/qla2x00t-32gbit/qla_mid.c index afa59b485..c7caf322f 100644 --- a/qla2x00t-32gbit/qla_mid.c +++ b/qla2x00t-32gbit/qla_mid.c @@ -807,11 +807,9 @@ static void qla_do_work(struct work_struct *work) { unsigned long flags; struct qla_qpair *qpair = container_of(work, struct qla_qpair, q_work); - struct scsi_qla_host *vha; - struct qla_hw_data *ha = qpair->hw; + struct scsi_qla_host *vha = qpair->vha; spin_lock_irqsave(&qpair->qp_lock, flags); - vha = pci_get_drvdata(ha->pdev); qla24xx_process_response_queue(vha, qpair->rsp); spin_unlock_irqrestore(&qpair->qp_lock, flags); diff --git a/qla2x00t-32gbit/qla_nvme.c b/qla2x00t-32gbit/qla_nvme.c index 1b4a26de5..e3b6ce4b3 100644 --- a/qla2x00t-32gbit/qla_nvme.c +++ b/qla2x00t-32gbit/qla_nvme.c @@ -440,8 +440,8 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp) /* No data transfer how do we check buffer len == 0?? */ if (fd->io_dir == NVMEFC_FCP_READ) { cmd_pkt->control_flags = cpu_to_le16(CF_READ_DATA); - vha->qla_stats.input_bytes += fd->payload_length; - vha->qla_stats.input_requests++; + qpair->counters.input_bytes += fd->payload_length; + qpair->counters.input_requests++; } else if (fd->io_dir == NVMEFC_FCP_WRITE) { cmd_pkt->control_flags = cpu_to_le16(CF_WRITE_DATA); if ((vha->flags.nvme_first_burst) && @@ -453,8 +453,8 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp) cmd_pkt->control_flags |= cpu_to_le16(CF_NVME_FIRST_BURST_ENABLE); } - vha->qla_stats.output_bytes += fd->payload_length; - vha->qla_stats.output_requests++; + qpair->counters.output_bytes += fd->payload_length; + qpair->counters.output_requests++; } else if (fd->io_dir == 0) { cmd_pkt->control_flags = 0; } diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 112299b38..47f9f3e26 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -7249,8 +7249,10 @@ qla2x00_timer(struct timer_list *t) * FC-NVME * see if the active AEN count has changed from what was last reported. */ + index = atomic_read(&ha->nvme_active_aen_cnt); if (!vha->vp_idx && - (atomic_read(&ha->nvme_active_aen_cnt) != ha->nvme_last_rptd_aen) && + (index != ha->nvme_last_rptd_aen) && + (index >= DEFAULT_ZIO_THRESHOLD) && ha->zio_mode == QLA_ZIO_MODE_6 && !ha->flags.host_shutting_down) { ql_log(ql_log_info, vha, 0x3002, @@ -7262,9 +7264,8 @@ qla2x00_timer(struct timer_list *t) } if (!vha->vp_idx && - (atomic_read(&ha->zio_threshold) != ha->last_zio_threshold) && - (ha->zio_mode == QLA_ZIO_MODE_6) && - (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha))) { + atomic_read(&ha->zio_threshold) != ha->last_zio_threshold && + IS_ZIO_THRESHOLD_CAPABLE(ha)) { ql_log(ql_log_info, vha, 0x3002, "Sched: Set ZIO exchange threshold to %d.\n", ha->last_zio_threshold); From e5b56feaef9aa4e3454d9355cdfc2c9a7e9c18d8 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 22:53:12 +0000 Subject: [PATCH 17/56] qla2x00t-32gbit: Fix I/O errors during LIP reset tests In .fcp_io(), returning ENODEV as soon as remote port delete has started can cause I/O errors. Fix this by returning EBUSY until the remote port delete finishes. Link: https://lore.kernel.org/r/20200904045128.23631-9-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit a35f87bdcc0615c5a3a695d13dd1ccf827826368. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9263 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_nvme.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/qla2x00t-32gbit/qla_nvme.c b/qla2x00t-32gbit/qla_nvme.c index e3b6ce4b3..74a84c7bf 100644 --- a/qla2x00t-32gbit/qla_nvme.c +++ b/qla2x00t-32gbit/qla_nvme.c @@ -560,6 +560,14 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport, return rval; vha = fcport->vha; + + if (!(fcport->nvme_flag & NVME_FLAG_REGISTERED)) + return rval; + + if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) || + (qpair && !qpair->fw_started) || fcport->deleted) + return -EBUSY; + /* * If we know the dev is going away while the transport is still sending * IO's return busy back to stall the IO Q. This happens when the From 51c390f09d78eeaebda487ceddf8df8102fd3ae1 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 22:54:00 +0000 Subject: [PATCH 18/56] qla2x00t-32gbit: Make tgt_port_database available in initiator mode tgt_port_database data is today exported only in target mode, allow it to be shown in initiator mode as well. Link: https://lore.kernel.org/r/20200904045128.23631-10-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit 4e5a05d1ecd92cec59b11c33821b5407984df81d. --- drivers/scsi/qla2xxx/qla_dfs.c | 64 +++++++++++++++++----------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c index 616ce891818d..1e9db568aee3 100644 --- a/drivers/scsi/qla2xxx/qla_dfs.c +++ b/drivers/scsi/qla2xxx/qla_dfs.c @@ -138,51 +138,51 @@ qla2x00_dfs_tgt_port_database_show(struct seq_file *s, void *unused) { scsi_qla_host_t *vha = s->private; struct qla_hw_data *ha = vha->hw; - struct gid_list_info *gid_list, *gid; + struct gid_list_info *gid_list; dma_addr_t gid_list_dma; fc_port_t fc_port; + char *id_iter; int rc, i; uint16_t entries, loop_id; - struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; seq_printf(s, "%s\n", vha->host_str); - if (tgt) { - gid_list = dma_alloc_coherent(&ha->pdev->dev, - qla2x00_gid_list_size(ha), - &gid_list_dma, GFP_KERNEL); - if (!gid_list) { - ql_dbg(ql_dbg_user, vha, 0x7018, - "DMA allocation failed for %u\n", - qla2x00_gid_list_size(ha)); - return 0; - } + gid_list = dma_alloc_coherent(&ha->pdev->dev, + qla2x00_gid_list_size(ha), + &gid_list_dma, GFP_KERNEL); + if (!gid_list) { + ql_dbg(ql_dbg_user, vha, 0x7018, + "DMA allocation failed for %u\n", + qla2x00_gid_list_size(ha)); + return 0; + } - rc = qla24xx_gidlist_wait(vha, gid_list, gid_list_dma, - &entries); - if (rc != QLA_SUCCESS) - goto out_free_id_list; + rc = qla24xx_gidlist_wait(vha, gid_list, gid_list_dma, + &entries); + if (rc != QLA_SUCCESS) + goto out_free_id_list; - gid = gid_list; + id_iter = (char *)gid_list; - seq_puts(s, "Port Name Port ID Loop ID\n"); + seq_puts(s, "Port Name Port ID Loop ID\n"); - for (i = 0; i < entries; i++) { - loop_id = le16_to_cpu(gid->loop_id); - memset(&fc_port, 0, sizeof(fc_port_t)); + for (i = 0; i < entries; i++) { + struct gid_list_info *gid = + (struct gid_list_info *)id_iter; + loop_id = le16_to_cpu(gid->loop_id); + memset(&fc_port, 0, sizeof(fc_port_t)); - fc_port.loop_id = loop_id; + fc_port.loop_id = loop_id; - rc = qla24xx_gpdb_wait(vha, &fc_port, 0); - seq_printf(s, "%8phC %02x%02x%02x %d\n", - fc_port.port_name, fc_port.d_id.b.domain, - fc_port.d_id.b.area, fc_port.d_id.b.al_pa, - fc_port.loop_id); - gid = (void *)gid + ha->gid_list_info_size; - } -out_free_id_list: - dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), - gid_list, gid_list_dma); + rc = qla24xx_gpdb_wait(vha, &fc_port, 0); + seq_printf(s, "%8phC %02x%02x%02x %d\n", + fc_port.port_name, fc_port.d_id.b.domain, + fc_port.d_id.b.area, fc_port.d_id.b.al_pa, + fc_port.loop_id); + id_iter += ha->gid_list_info_size; } +out_free_id_list: + dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), + gid_list, gid_list_dma); return 0; } git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9264 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_dfs.c | 76 +++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/qla2x00t-32gbit/qla_dfs.c b/qla2x00t-32gbit/qla_dfs.c index beffb179f..86e80c5e8 100644 --- a/qla2x00t-32gbit/qla_dfs.c +++ b/qla2x00t-32gbit/qla_dfs.c @@ -137,52 +137,52 @@ qla2x00_dfs_tgt_port_database_show(struct seq_file *s, void *unused) { scsi_qla_host_t *vha = s->private; struct qla_hw_data *ha = vha->hw; - struct gid_list_info *gid_list, *gid; + struct gid_list_info *gid_list; dma_addr_t gid_list_dma; fc_port_t fc_port; + char *id_iter; int rc, i; uint16_t entries, loop_id; - struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; seq_printf(s, "%s\n", vha->host_str); - if (tgt) { - gid_list = dma_alloc_coherent(&ha->pdev->dev, - qla2x00_gid_list_size(ha), - &gid_list_dma, GFP_KERNEL); - if (!gid_list) { - ql_dbg(ql_dbg_user, vha, 0x7018, - "DMA allocation failed for %u\n", - qla2x00_gid_list_size(ha)); - return 0; - } - - rc = qla24xx_gidlist_wait(vha, gid_list, gid_list_dma, - &entries); - if (rc != QLA_SUCCESS) - goto out_free_id_list; - - gid = gid_list; - - seq_puts(s, "Port Name Port ID Loop ID\n"); - - for (i = 0; i < entries; i++) { - loop_id = le16_to_cpu(gid->loop_id); - memset(&fc_port, 0, sizeof(fc_port_t)); - - fc_port.loop_id = loop_id; - - rc = qla24xx_gpdb_wait(vha, &fc_port, 0); - seq_printf(s, "%8phC %02x%02x%02x %d\n", - fc_port.port_name, fc_port.d_id.b.domain, - fc_port.d_id.b.area, fc_port.d_id.b.al_pa, - fc_port.loop_id); - gid = (void *)gid + ha->gid_list_info_size; - } -out_free_id_list: - dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), - gid_list, gid_list_dma); + gid_list = dma_alloc_coherent(&ha->pdev->dev, + qla2x00_gid_list_size(ha), + &gid_list_dma, GFP_KERNEL); + if (!gid_list) { + ql_dbg(ql_dbg_user, vha, 0x7018, + "DMA allocation failed for %u\n", + qla2x00_gid_list_size(ha)); + return 0; } + rc = qla24xx_gidlist_wait(vha, gid_list, gid_list_dma, + &entries); + if (rc != QLA_SUCCESS) + goto out_free_id_list; + + id_iter = (char *)gid_list; + + seq_puts(s, "Port Name Port ID Loop ID\n"); + + for (i = 0; i < entries; i++) { + struct gid_list_info *gid = + (struct gid_list_info *)id_iter; + loop_id = le16_to_cpu(gid->loop_id); + memset(&fc_port, 0, sizeof(fc_port_t)); + + fc_port.loop_id = loop_id; + + rc = qla24xx_gpdb_wait(vha, &fc_port, 0); + seq_printf(s, "%8phC %02x%02x%02x %d\n", + fc_port.port_name, fc_port.d_id.b.domain, + fc_port.d_id.b.area, fc_port.d_id.b.al_pa, + fc_port.loop_id); + id_iter += ha->gid_list_info_size; + } +out_free_id_list: + dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), + gid_list, gid_list_dma); + return 0; } From dc06ae2b083d2b6692f285090e9ba78123e32b4d Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 22:54:58 +0000 Subject: [PATCH 19/56] qla2x00t-32gbit: Add rport fields in debugfs This patch adds rport fields in debugfs. Link: https://lore.kernel.org/r/20200904045128.23631-11-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit 6152d20fa6703cf364253efc4eab31151558cb01. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9265 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_dfs.c | 53 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/qla2x00t-32gbit/qla_dfs.c b/qla2x00t-32gbit/qla_dfs.c index 86e80c5e8..6de10f5dd 100644 --- a/qla2x00t-32gbit/qla_dfs.c +++ b/qla2x00t-32gbit/qla_dfs.c @@ -64,13 +64,53 @@ DEFINE_DEBUGFS_ATTRIBUTE(qla_dfs_rport_##_attr##_fops, \ qla_dfs_rport_##_attr##_get, \ qla_dfs_rport_##_attr##_set, "%llu\n") +/* + * Wrapper for getting fc_port fields. + * + * _attr : Attribute name. + * _get_val : Accessor macro to retrieve the value. + */ +#define DEFINE_QLA_DFS_RPORT_FIELD_GET(_attr, _get_val) \ +static int qla_dfs_rport_field_##_attr##_get(void *data, u64 *val) \ +{ \ + struct fc_port *fp = data; \ + *val = _get_val; \ + return 0; \ +} \ +DEFINE_DEBUGFS_ATTRIBUTE(qla_dfs_rport_field_##_attr##_fops, \ + qla_dfs_rport_field_##_attr##_get, \ + NULL, "%llu\n") + +#define DEFINE_QLA_DFS_RPORT_ACCESS(_attr, _get_val) \ + DEFINE_QLA_DFS_RPORT_FIELD_GET(_attr, _get_val) + +#define DEFINE_QLA_DFS_RPORT_FIELD(_attr) \ + DEFINE_QLA_DFS_RPORT_FIELD_GET(_attr, fp->_attr) + DEFINE_QLA_DFS_RPORT_RW_ATTR(QLA_DFS_RPORT_DEVLOSS_TMO, dev_loss_tmo); +DEFINE_QLA_DFS_RPORT_FIELD(disc_state); +DEFINE_QLA_DFS_RPORT_FIELD(scan_state); +DEFINE_QLA_DFS_RPORT_FIELD(fw_login_state); +DEFINE_QLA_DFS_RPORT_FIELD(login_pause); +DEFINE_QLA_DFS_RPORT_FIELD(flags); +DEFINE_QLA_DFS_RPORT_FIELD(nvme_flag); +DEFINE_QLA_DFS_RPORT_FIELD(last_rscn_gen); +DEFINE_QLA_DFS_RPORT_FIELD(rscn_gen); +DEFINE_QLA_DFS_RPORT_FIELD(login_gen); +DEFINE_QLA_DFS_RPORT_FIELD(loop_id); +DEFINE_QLA_DFS_RPORT_FIELD_GET(port_id, fp->d_id.b24); +DEFINE_QLA_DFS_RPORT_FIELD_GET(sess_kref, kref_read(&fp->sess_kref)); + void qla2x00_dfs_create_rport(scsi_qla_host_t *vha, struct fc_port *fp) { char wwn[32]; +#define QLA_CREATE_RPORT_FIELD_ATTR(_attr) \ + debugfs_create_file(#_attr, 0400, fp->dfs_rport_dir, \ + fp, &qla_dfs_rport_field_##_attr##_fops) + if (!vha->dfs_rport_root || fp->dfs_rport_dir) return; @@ -81,6 +121,19 @@ qla2x00_dfs_create_rport(scsi_qla_host_t *vha, struct fc_port *fp) if (NVME_TARGET(vha->hw, fp)) debugfs_create_file("dev_loss_tmo", 0600, fp->dfs_rport_dir, fp, &qla_dfs_rport_dev_loss_tmo_fops); + + QLA_CREATE_RPORT_FIELD_ATTR(disc_state); + QLA_CREATE_RPORT_FIELD_ATTR(scan_state); + QLA_CREATE_RPORT_FIELD_ATTR(fw_login_state); + QLA_CREATE_RPORT_FIELD_ATTR(login_pause); + QLA_CREATE_RPORT_FIELD_ATTR(flags); + QLA_CREATE_RPORT_FIELD_ATTR(nvme_flag); + QLA_CREATE_RPORT_FIELD_ATTR(last_rscn_gen); + QLA_CREATE_RPORT_FIELD_ATTR(rscn_gen); + QLA_CREATE_RPORT_FIELD_ATTR(login_gen); + QLA_CREATE_RPORT_FIELD_ATTR(loop_id); + QLA_CREATE_RPORT_FIELD_ATTR(port_id); + QLA_CREATE_RPORT_FIELD_ATTR(sess_kref); } void From 49f618cea5736a6c65f0610037aadddf179b72fb Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 22:56:20 +0000 Subject: [PATCH 20/56] qla2x00t-32gbit: Add IOCB resource tracking This patch tracks number of IOCB resources used in the I/O fast path. If the number of used IOCBs reach a high water limit, driver would return the I/O as busy and let upper layer retry. This prevents over subscription of IOCB resources where any future error recovery command is unable to cut through. Enable IOCB throttling by default. Link: https://lore.kernel.org/r/20200904045128.23631-12-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit 89c72f4245a8510ffdb0d1980944210b8bc6e49f. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9266 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 17 +++++++++++ qla2x00t-32gbit/qla_dfs.c | 14 +++++++++ qla2x00t-32gbit/qla_gbl.h | 3 ++ qla2x00t-32gbit/qla_init.c | 26 +++++++++++++++++ qla2x00t-32gbit/qla_inline.h | 55 ++++++++++++++++++++++++++++++++++++ qla2x00t-32gbit/qla_iocb.c | 28 ++++++++++++++++++ qla2x00t-32gbit/qla_isr.c | 2 ++ qla2x00t-32gbit/qla_os.c | 6 ++++ 8 files changed, 151 insertions(+) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index 5b5decc3b..f78a1f1ab 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -645,6 +645,12 @@ enum { TYPE_TGT_TMCMD, /* task management */ }; +struct iocb_resource { + u8 res_type; + u8 pad; + u16 iocb_cnt; +}; + typedef struct srb { /* * Do not move cmd_type field, it needs to @@ -652,6 +658,7 @@ typedef struct srb { */ uint8_t cmd_type; uint8_t pad[3]; + struct iocb_resource iores; struct kref cmd_kref; /* need to migrate ref_count over to this */ void *priv; wait_queue_head_t nvme_ls_waitq; @@ -3603,6 +3610,15 @@ struct req_que { uint8_t req_pkt[REQUEST_ENTRY_SIZE]; }; +struct qla_fw_resources { + u16 iocbs_total; + u16 iocbs_limit; + u16 iocbs_qp_limit; + u16 iocbs_used; +}; + +#define QLA_IOCB_PCT_LIMIT 95 + /*Queue pair data structure */ struct qla_qpair { spinlock_t qp_lock; @@ -3655,6 +3671,7 @@ struct qla_qpair { uint64_t retry_term_jiff; struct qla_tgt_counters tgt_counters; uint16_t cpuid; + struct qla_fw_resources fwres ____cacheline_aligned; }; /* Place holder for FW buffer parameters */ diff --git a/qla2x00t-32gbit/qla_dfs.c b/qla2x00t-32gbit/qla_dfs.c index 6de10f5dd..f89ad3274 100644 --- a/qla2x00t-32gbit/qla_dfs.c +++ b/qla2x00t-32gbit/qla_dfs.c @@ -260,6 +260,8 @@ qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused) struct scsi_qla_host *vha = s->private; uint16_t mb[MAX_IOCB_MB_REG]; int rc; + struct qla_hw_data *ha = vha->hw; + u16 iocbs_used, i; rc = qla24xx_res_count_wait(vha, mb, SIZEOF_IOCB_MB_REG); if (rc != QLA_SUCCESS) { @@ -284,6 +286,18 @@ qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused) mb[23]); } + if (ql2xenforce_iocb_limit) { + /* lock is not require. It's an estimate. */ + iocbs_used = ha->base_qpair->fwres.iocbs_used; + for (i = 0; i < ha->max_qpairs; i++) { + if (ha->queue_pair_map[i]) + iocbs_used += ha->queue_pair_map[i]->fwres.iocbs_used; + } + + seq_printf(s, "Driver: estimate iocb used [%d] high water limit [%d]\n", + iocbs_used, ha->base_qpair->fwres.iocbs_limit); + } + return 0; } diff --git a/qla2x00t-32gbit/qla_gbl.h b/qla2x00t-32gbit/qla_gbl.h index 94941fd30..727a70a66 100644 --- a/qla2x00t-32gbit/qla_gbl.h +++ b/qla2x00t-32gbit/qla_gbl.h @@ -128,6 +128,8 @@ int qla2x00_reserve_mgmt_server_loop_id(scsi_qla_host_t *); void qla_rscn_replay(fc_port_t *fcport); void qla24xx_free_purex_item(struct purex_item *item); extern bool qla24xx_risc_firmware_invalid(uint32_t *); +void qla_init_iocb_limit(scsi_qla_host_t *); + /* * Global Data in qla_os.c source file. @@ -178,6 +180,7 @@ extern int qla2xuseresexchforels; extern int ql2xexlogins; extern int ql2xdifbundlinginternalbuffers; extern int ql2xfulldump_on_mpifail; +extern int ql2xenforce_iocb_limit; extern int qla2x00_loop_reset(scsi_qla_host_t *); extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int); diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index a4ff8e5a3..e331bd919 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -3631,6 +3631,31 @@ out: return ha->flags.lr_detected; } +void qla_init_iocb_limit(scsi_qla_host_t *vha) +{ + u16 i, num_qps; + u32 limit; + struct qla_hw_data *ha = vha->hw; + + num_qps = ha->num_qpairs + 1; + limit = (ha->orig_fw_iocb_count * QLA_IOCB_PCT_LIMIT) / 100; + + ha->base_qpair->fwres.iocbs_total = ha->orig_fw_iocb_count; + ha->base_qpair->fwres.iocbs_limit = limit; + ha->base_qpair->fwres.iocbs_qp_limit = limit / num_qps; + ha->base_qpair->fwres.iocbs_used = 0; + for (i = 0; i < ha->max_qpairs; i++) { + if (ha->queue_pair_map[i]) { + ha->queue_pair_map[i]->fwres.iocbs_total = + ha->orig_fw_iocb_count; + ha->queue_pair_map[i]->fwres.iocbs_limit = limit; + ha->queue_pair_map[i]->fwres.iocbs_qp_limit = + limit / num_qps; + ha->queue_pair_map[i]->fwres.iocbs_used = 0; + } + } +} + /** * qla2x00_setup_chip() - Load and start RISC firmware. * @vha: HA context @@ -3730,6 +3755,7 @@ enable_82xx_npiv: MIN_MULTI_ID_FABRIC - 1; } qla2x00_get_resource_cnts(vha); + qla_init_iocb_limit(vha); /* * Allocate the array of outstanding commands diff --git a/qla2x00t-32gbit/qla_inline.h b/qla2x00t-32gbit/qla_inline.h index f7f13a6e4..ca33521e2 100644 --- a/qla2x00t-32gbit/qla_inline.h +++ b/qla2x00t-32gbit/qla_inline.h @@ -385,3 +385,58 @@ qla2xxx_get_fc4_priority(struct scsi_qla_host *vha) return (data >> 6) & BIT_0 ? FC4_PRIORITY_FCP : FC4_PRIORITY_NVME; } + +enum { + RESOURCE_NONE, + RESOURCE_INI, +}; + +static inline int +qla_get_iocbs(struct qla_qpair *qp, struct iocb_resource *iores) +{ + u16 iocbs_used, i; + struct qla_hw_data *ha = qp->vha->hw; + + if (!ql2xenforce_iocb_limit) { + iores->res_type = RESOURCE_NONE; + return 0; + } + + if ((iores->iocb_cnt + qp->fwres.iocbs_used) < qp->fwres.iocbs_qp_limit) { + qp->fwres.iocbs_used += iores->iocb_cnt; + return 0; + } else { + /* no need to acquire qpair lock. It's just rough calculation */ + iocbs_used = ha->base_qpair->fwres.iocbs_used; + for (i = 0; i < ha->max_qpairs; i++) { + if (ha->queue_pair_map[i]) + iocbs_used += ha->queue_pair_map[i]->fwres.iocbs_used; + } + + if ((iores->iocb_cnt + iocbs_used) < qp->fwres.iocbs_limit) { + qp->fwres.iocbs_used += iores->iocb_cnt; + return 0; + } else { + iores->res_type = RESOURCE_NONE; + return -ENOSPC; + } + } +} + +static inline void +qla_put_iocbs(struct qla_qpair *qp, struct iocb_resource *iores) +{ + switch (iores->res_type) { + case RESOURCE_NONE: + break; + default: + if (qp->fwres.iocbs_used >= iores->iocb_cnt) { + qp->fwres.iocbs_used -= iores->iocb_cnt; + } else { + // should not happen + qp->fwres.iocbs_used = 0; + } + break; + } + iores->res_type = RESOURCE_NONE; +} diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index 2b59c18dd..009ab8b6a 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -1642,6 +1642,12 @@ qla24xx_start_scsi(srb_t *sp) tot_dsds = nseg; req_cnt = qla24xx_calc_iocbs(vha, tot_dsds); + + sp->iores.res_type = RESOURCE_INI; + sp->iores.iocb_cnt = req_cnt; + if (qla_get_iocbs(sp->qpair, &sp->iores)) + goto queuing_error; + if (req->cnt < (req_cnt + 2)) { cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr : rd_reg_dword_relaxed(req->req_q_out); @@ -1714,6 +1720,7 @@ queuing_error: if (tot_dsds) scsi_dma_unmap(cmd); + qla_put_iocbs(sp->qpair, &sp->iores); spin_unlock_irqrestore(&ha->hardware_lock, flags); return QLA_FUNCTION_FAILED; @@ -1827,6 +1834,12 @@ qla24xx_dif_start_scsi(srb_t *sp) /* Total Data and protection sg segment(s) */ tot_prot_dsds = nseg; tot_dsds += nseg; + + sp->iores.res_type = RESOURCE_INI; + sp->iores.iocb_cnt = qla24xx_calc_iocbs(vha, tot_dsds); + if (qla_get_iocbs(sp->qpair, &sp->iores)) + goto queuing_error; + if (req->cnt < (req_cnt + 2)) { cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr : rd_reg_dword_relaxed(req->req_q_out); @@ -1901,6 +1914,7 @@ queuing_error: } /* Cleanup will be performed by the caller (queuecommand) */ + qla_put_iocbs(sp->qpair, &sp->iores); spin_unlock_irqrestore(&ha->hardware_lock, flags); return QLA_FUNCTION_FAILED; } @@ -1962,6 +1976,12 @@ qla2xxx_start_scsi_mq(srb_t *sp) tot_dsds = nseg; req_cnt = qla24xx_calc_iocbs(vha, tot_dsds); + + sp->iores.res_type = RESOURCE_INI; + sp->iores.iocb_cnt = req_cnt; + if (qla_get_iocbs(sp->qpair, &sp->iores)) + goto queuing_error; + if (req->cnt < (req_cnt + 2)) { cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr : rd_reg_dword_relaxed(req->req_q_out); @@ -2034,6 +2054,7 @@ queuing_error: if (tot_dsds) scsi_dma_unmap(cmd); + qla_put_iocbs(sp->qpair, &sp->iores); spin_unlock_irqrestore(&qpair->qp_lock, flags); return QLA_FUNCTION_FAILED; @@ -2162,6 +2183,12 @@ qla2xxx_dif_start_scsi_mq(srb_t *sp) /* Total Data and protection sg segment(s) */ tot_prot_dsds = nseg; tot_dsds += nseg; + + sp->iores.res_type = RESOURCE_INI; + sp->iores.iocb_cnt = qla24xx_calc_iocbs(vha, tot_dsds); + if (qla_get_iocbs(sp->qpair, &sp->iores)) + goto queuing_error; + if (req->cnt < (req_cnt + 2)) { cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr : rd_reg_dword_relaxed(req->req_q_out); @@ -2239,6 +2266,7 @@ queuing_error: } /* Cleanup will be performed by the caller (queuecommand) */ + qla_put_iocbs(sp->qpair, &sp->iores); spin_unlock_irqrestore(&qpair->qp_lock, flags); return QLA_FUNCTION_FAILED; } diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index 1d5c62635..264e2a3ab 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -2935,6 +2935,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) } return; } + qla_put_iocbs(sp->qpair, &sp->iores); if (sp->cmd_type != TYPE_SRB) { req->outstanding_cmds[handle] = NULL; @@ -3347,6 +3348,7 @@ qla2x00_error_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, sts_entry_t *pkt) default: sp = qla2x00_get_sp_from_handle(vha, func, req, pkt); if (sp) { + qla_put_iocbs(sp->qpair, &sp->iores); sp->done(sp, res); return 0; } diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 47f9f3e26..892e42a36 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -52,6 +52,11 @@ module_param(ql2xfulldump_on_mpifail, int, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(ql2xfulldump_on_mpifail, "Set this to take full dump on MPI hang."); +int ql2xenforce_iocb_limit = 1; +module_param(ql2xenforce_iocb_limit, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(ql2xenforce_iocb_limit, + "Enforce IOCB throttling, to avoid FW congestion. (default: 0)"); + /* * CT6 CTX allocation cache */ @@ -3363,6 +3368,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) for (i = 0; i < ha->max_qpairs; i++) qla2xxx_create_qpair(base_vha, 5, 0, startit); } + qla_init_iocb_limit(base_vha); if (ha->flags.running_gold_fw) goto skip_dpc; From 4e99fc582fa1c7198887bd42bcb921c9490c3968 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 22:57:26 +0000 Subject: [PATCH 21/56] qla2x00t-32gbit: Add SLER and PI control support BIT_13 of extended FW attribute informs about NVMe-2 support. Set BIT_15 of special feature control block for enabling SLER in FW. Set bit 8 (SLER supported) to 1 for the service parameter information when sending NVMe PRLI request. Set BIT_14 of special feature control block for enabling PI Control in FW. Driver should set bit 9 (PI Control supported) to 1 for the service parameter information when sending NVMe PRLI request. Set BIT_13 for NVMe Async events. Link: https://lore.kernel.org/r/20200904045128.23631-13-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Saurav Kashyap Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit cf3c54fb49a4eb5b5b83ddab0b25df47b2e958af. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9267 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_dbg.c | 2 +- qla2x00t-32gbit/qla_def.h | 4 ++++ qla2x00t-32gbit/qla_iocb.c | 8 ++++++++ qla2x00t-32gbit/qla_mbx.c | 18 ++++++++++++++++-- qla2x00t-32gbit/qla_nvme.c | 16 ++++++++++++++-- qla2x00t-32gbit/qla_nvme.h | 1 + qla2x00t-32gbit/qla_os.c | 1 + 7 files changed, 45 insertions(+), 5 deletions(-) diff --git a/qla2x00t-32gbit/qla_dbg.c b/qla2x00t-32gbit/qla_dbg.c index 75a008512..1434789c9 100644 --- a/qla2x00t-32gbit/qla_dbg.c +++ b/qla2x00t-32gbit/qla_dbg.c @@ -15,7 +15,7 @@ * | Device Discovery | 0x2134 | 0x210e-0x2116 | * | | | 0x211a | * | | | 0x211c-0x2128 | - * | | | 0x212a-0x2134 | + * | | | 0x212c-0x2134 | * | Queue Command and IO tracing | 0x3074 | 0x300b | * | | | 0x3027-0x3028 | * | | | 0x303d-0x3041 | diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index f78a1f1ab..e2fc93091 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -2501,6 +2501,8 @@ typedef struct fc_port { struct completion nvme_del_done; uint32_t nvme_prli_service_param; +#define NVME_PRLI_SP_PI_CTRL BIT_9 +#define NVME_PRLI_SP_SLER BIT_8 #define NVME_PRLI_SP_CONF BIT_7 #define NVME_PRLI_SP_INITIATOR BIT_5 #define NVME_PRLI_SP_TARGET BIT_4 @@ -4335,6 +4337,7 @@ struct qla_hw_data { #define FW_ATTR_EXT0_SCM_BROCADE 0x00001000 /* Cisco fabric attached */ #define FW_ATTR_EXT0_SCM_CISCO 0x00002000 +#define FW_ATTR_EXT0_NVME2 BIT_13 uint16_t fw_attributes_ext[2]; uint32_t fw_memory_size; uint32_t fw_transfer_size; @@ -4684,6 +4687,7 @@ typedef struct scsi_qla_host { uint32_t qpairs_rsp_created:1; uint32_t nvme_enabled:1; uint32_t nvme_first_burst:1; + uint32_t nvme2_enabled:1; } flags; atomic_t loop_state; diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index 009ab8b6a..e2e74a48a 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -2383,6 +2383,14 @@ qla24xx_prli_iocb(srb_t *sp, struct logio_entry_24xx *logio) if (sp->vha->flags.nvme_first_burst) logio->io_parameter[0] = cpu_to_le32(NVME_PRLI_SP_FIRST_BURST); + if (sp->vha->flags.nvme2_enabled) { + /* Set service parameter BIT_8 for SLER support */ + logio->io_parameter[0] |= + cpu_to_le32(NVME_PRLI_SP_SLER); + /* Set service parameter BIT_9 for PI control support */ + logio->io_parameter[0] |= + cpu_to_le32(NVME_PRLI_SP_PI_CTRL); + } } logio->nport_handle = cpu_to_le16(sp->fcport->loop_id); diff --git a/qla2x00t-32gbit/qla_mbx.c b/qla2x00t-32gbit/qla_mbx.c index 0dff8e165..7bbbec59c 100644 --- a/qla2x00t-32gbit/qla_mbx.c +++ b/qla2x00t-32gbit/qla_mbx.c @@ -1092,6 +1092,14 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha) "%s: FC-NVMe is Enabled (0x%x)\n", __func__, ha->fw_attributes_h); } + + /* BIT_13 of Extended FW Attributes informs about NVMe2 support */ + if (ha->fw_attributes_ext[0] & FW_ATTR_EXT0_NVME2) { + ql_log(ql_log_info, vha, 0xd302, + "Firmware supports NVMe2 0x%x\n", + ha->fw_attributes_ext[0]); + vha->flags.nvme2_enabled = 1; + } } if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { @@ -1121,12 +1129,18 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha) if (ha->flags.scm_supported_a && (ha->fw_attributes_ext[0] & FW_ATTR_EXT0_SCM_SUPPORTED)) { ha->flags.scm_supported_f = 1; - memset(ha->sf_init_cb, 0, sizeof(struct init_sf_cb)); ha->sf_init_cb->flags |= BIT_13; } ql_log(ql_log_info, vha, 0x11a3, "SCM in FW: %s\n", (ha->flags.scm_supported_f) ? "Supported" : "Not Supported"); + + if (vha->flags.nvme2_enabled) { + /* set BIT_15 of special feature control block for SLER */ + ha->sf_init_cb->flags |= BIT_15; + /* set BIT_14 of special feature control block for PI CTRL*/ + ha->sf_init_cb->flags |= BIT_14; + } } failed: @@ -1822,7 +1836,7 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size) mcp->out_mb |= MBX_14|MBX_13|MBX_12|MBX_11|MBX_10; } - if (ha->flags.scm_supported_f) { + if (ha->flags.scm_supported_f || vha->flags.nvme2_enabled) { mcp->mb[1] |= BIT_1; mcp->mb[16] = MSW(ha->sf_init_cb_dma); mcp->mb[17] = LSW(ha->sf_init_cb_dma); diff --git a/qla2x00t-32gbit/qla_nvme.c b/qla2x00t-32gbit/qla_nvme.c index 74a84c7bf..fe4cf7cb8 100644 --- a/qla2x00t-32gbit/qla_nvme.c +++ b/qla2x00t-32gbit/qla_nvme.c @@ -81,6 +81,14 @@ int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport) return ret; } + if (fcport->nvme_prli_service_param & NVME_PRLI_SP_SLER) + ql_log(ql_log_info, vha, 0x212a, + "PortID:%06x Supports SLER\n", req.port_id); + + if (fcport->nvme_prli_service_param & NVME_PRLI_SP_PI_CTRL) + ql_log(ql_log_info, vha, 0x212b, + "PortID:%06x Supports PI control\n", req.port_id); + rport = fcport->nvme_remote_port->private; rport->fcport = fcport; @@ -380,6 +388,7 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp) struct srb_iocb *nvme = &sp->u.iocb_cmd; struct scatterlist *sgl, *sg; struct nvmefc_fcp_req *fd = nvme->u.nvme.desc; + struct nvme_fc_cmd_iu *cmd = fd->cmdaddr; uint32_t rval = QLA_SUCCESS; /* Setup qpair pointers */ @@ -411,8 +420,6 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp) } if (unlikely(!fd->sqid)) { - struct nvme_fc_cmd_iu *cmd = fd->cmdaddr; - if (cmd->sqe.common.opcode == nvme_admin_async_event) { nvme->u.nvme.aen_op = 1; atomic_inc(&ha->nvme_active_aen_cnt); @@ -458,6 +465,11 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp) } else if (fd->io_dir == 0) { cmd_pkt->control_flags = 0; } + /* Set BIT_13 of control flags for Async event */ + if (vha->flags.nvme2_enabled && + cmd->sqe.common.opcode == nvme_admin_async_event) { + cmd_pkt->control_flags |= cpu_to_le16(CF_ADMIN_ASYNC_EVENT); + } /* Set NPORT-ID */ cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id); diff --git a/qla2x00t-32gbit/qla_nvme.h b/qla2x00t-32gbit/qla_nvme.h index 54a7e8d40..c2e8da288 100644 --- a/qla2x00t-32gbit/qla_nvme.h +++ b/qla2x00t-32gbit/qla_nvme.h @@ -56,6 +56,7 @@ struct cmd_nvme { uint64_t rsvd; __le16 control_flags; /* Control Flags */ +#define CF_ADMIN_ASYNC_EVENT BIT_13 #define CF_NVME_FIRST_BURST_ENABLE BIT_11 #define CF_DIF_SEG_DESCR_ENABLE BIT_3 #define CF_DATA_SEG_DESCR_ENABLE BIT_2 diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 892e42a36..84d04155b 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -4278,6 +4278,7 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, &ha->sf_init_cb_dma); if (!ha->sf_init_cb) goto fail_sf_init_cb; + memset(ha->sf_init_cb, 0, sizeof(struct init_sf_cb)); ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0199, "sf_init_cb=%p.\n", ha->sf_init_cb); } From 411c5b0e1b5d2e6afc0462cec5ed3bc4401df287 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 22:58:16 +0000 Subject: [PATCH 22/56] qla2x00t-32gbit: Update version to 10.02.00.102-k Update internal driver version and remove module version macro. Link: https://lore.kernel.org/r/20200904045128.23631-14-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit 767c8457b729e774f5a4646f60a0598ab868c798. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9268 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 1 - qla2x00t-32gbit/qla_version.h | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 84d04155b..e52a74b34 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -8077,7 +8077,6 @@ module_exit(qla2x00_module_exit); MODULE_AUTHOR("QLogic Corporation"); MODULE_DESCRIPTION("QLogic Fibre Channel HBA Driver"); MODULE_LICENSE("GPL"); -MODULE_VERSION(QLA2XXX_VERSION); MODULE_FIRMWARE(FW_FILE_ISP21XX); MODULE_FIRMWARE(FW_FILE_ISP22XX); MODULE_FIRMWARE(FW_FILE_ISP2300); diff --git a/qla2x00t-32gbit/qla_version.h b/qla2x00t-32gbit/qla_version.h index 3ca1fb968..d3205b52f 100644 --- a/qla2x00t-32gbit/qla_version.h +++ b/qla2x00t-32gbit/qla_version.h @@ -6,9 +6,9 @@ /* * Driver version */ -#define QLA2XXX_VERSION "10.01.00.25-k" +#define QLA2XXX_VERSION "10.02.00.102-k" #define QLA_DRIVER_MAJOR_VER 10 -#define QLA_DRIVER_MINOR_VER 1 +#define QLA_DRIVER_MINOR_VER 2 #define QLA_DRIVER_PATCH_VER 0 -#define QLA_DRIVER_BETA_VER 0 +#define QLA_DRIVER_BETA_VER 102 From f78ec93f05437f97b72e2383dafeaabde8099cf1 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 22:59:11 +0000 Subject: [PATCH 23/56] qla2x00t-32gbit: Correct the check for sscanf() return value Since the version string has been modified, sscanf() returns 4 instead of 6. Link: https://lore.kernel.org/r/20200929102152.32278-2-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Saurav Kashyap Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit 7dc0f671d89c03db95db3d4cd57257790d7a4b80. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9269 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_tmpl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_tmpl.c b/qla2x00t-32gbit/qla_tmpl.c index 03fff32b5..5273e3e9e 100644 --- a/qla2x00t-32gbit/qla_tmpl.c +++ b/qla2x00t-32gbit/qla_tmpl.c @@ -905,8 +905,8 @@ qla27xx_driver_info(struct qla27xx_fwdt_template *tmp) uint8_t v[] = { 0, 0, 0, 0, 0, 0 }; WARN_ON_ONCE(sscanf(qla2x00_version_str, - "%hhu.%hhu.%hhu.%hhu.%hhu.%hhu", - v+0, v+1, v+2, v+3, v+4, v+5) != 6); + "%hhu.%hhu.%hhu.%hhu", + v + 0, v + 1, v + 2, v + 3) != 4); tmp->driver_info[0] = cpu_to_le32( v[3] << 24 | v[2] << 16 | v[1] << 8 | v[0]); From fa9bf1534057f4a7c08f0780a9158e430c1d7213 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:00:18 +0000 Subject: [PATCH 24/56] qla2x00t-32gbit: Fix buffer-buffer credit extraction error Current code uses wrong mailbox option to extract bbc from firmware. This field is nested inside of PLOGI payload. Extract bbc from PLOGI template payload. Link: https://lore.kernel.org/r/20200929102152.32278-3-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit 44f5a37d1e3e4e392412318666f8477601ae3024. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9270 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 4 ++- qla2x00t-32gbit/qla_init.c | 50 ++++++++++++++++++++------------------ qla2x00t-32gbit/qla_iocb.c | 3 +-- qla2x00t-32gbit/qla_mbx.c | 39 ----------------------------- qla2x00t-32gbit/qla_os.c | 19 +++------------ 5 files changed, 34 insertions(+), 81 deletions(-) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index e2fc93091..2bc052512 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -3941,6 +3941,7 @@ struct qla_hw_data { /* Enabled in Driver */ uint32_t scm_enabled:1; uint32_t max_req_queue_warned:1; + uint32_t plogi_template_valid:1; } flags; uint16_t max_exchg; @@ -4289,7 +4290,8 @@ struct qla_hw_data { int exchoffld_count; /* n2n */ - struct els_plogi_payload plogi_els_payld; + struct fc_els_flogi plogi_els_payld; +#define LOGIN_TEMPLATE_SIZE (sizeof(struct fc_els_flogi) - 4) void *swl; diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index e331bd919..6e44ad80b 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -4990,6 +4990,29 @@ qla2x00_free_fcport(fc_port_t *fcport) kfree(fcport); } +static void qla_get_login_template(scsi_qla_host_t *vha) +{ + struct qla_hw_data *ha = vha->hw; + int rval; + u32 *bp, sz; + __be32 *q; + + memset(ha->init_cb, 0, ha->init_cb_size); + sz = min_t(int, sizeof(struct fc_els_flogi), ha->init_cb_size); + rval = qla24xx_get_port_login_templ(vha, ha->init_cb_dma, + ha->init_cb, sz); + if (rval != QLA_SUCCESS) { + ql_dbg(ql_dbg_init, vha, 0x00d1, + "PLOGI ELS param read fail.\n"); + return; + } + q = (__be32 *)&ha->plogi_els_payld.fl_csp; + + bp = (uint32_t *)ha->init_cb; + cpu_to_be32_array(q, bp, sz / 4); + ha->flags.plogi_template_valid = 1; +} + /* * qla2x00_configure_loop * Updates Fibre Channel Device Database with what is actually on loop. @@ -5033,6 +5056,7 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) clear_bit(RSCN_UPDATE, &vha->dpc_flags); qla2x00_get_data_rate(vha); + qla_get_login_template(vha); /* Determine what we need to do */ if ((ha->current_topology == ISP_CFG_FL || @@ -5117,32 +5141,11 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) static int qla2x00_configure_n2n_loop(scsi_qla_host_t *vha) { - struct qla_hw_data *ha = vha->hw; unsigned long flags; fc_port_t *fcport; - int rval; - if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags)) { - /* borrowing */ - u32 *bp, sz; - - memset(ha->init_cb, 0, ha->init_cb_size); - sz = min_t(int, sizeof(struct els_plogi_payload), - ha->init_cb_size); - rval = qla24xx_get_port_login_templ(vha, ha->init_cb_dma, - ha->init_cb, sz); - if (rval == QLA_SUCCESS) { - __be32 *q = &ha->plogi_els_payld.data[0]; - - bp = (uint32_t *)ha->init_cb; - cpu_to_be32_array(q, bp, sz / 4); - memcpy(bp, q, sizeof(ha->plogi_els_payld.data)); - } else { - ql_dbg(ql_dbg_init, vha, 0x00d1, - "PLOGI ELS param read fail.\n"); - goto skip_login; - } - } + if (test_and_clear_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags)) + set_bit(RELOGIN_NEEDED, &vha->dpc_flags); list_for_each_entry(fcport, &vha->vp_fcports, list) { if (fcport->n2n_flag) { @@ -5151,7 +5154,6 @@ static int qla2x00_configure_n2n_loop(scsi_qla_host_t *vha) } } -skip_login: spin_lock_irqsave(&vha->work_lock, flags); vha->scan.scan_retry++; spin_unlock_irqrestore(&vha->work_lock, flags); diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index e2e74a48a..97e8f15b7 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -3018,8 +3018,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode, memset(ptr, 0, sizeof(struct els_plogi_payload)); memset(resp_ptr, 0, sizeof(struct els_plogi_payload)); memcpy(elsio->u.els_plogi.els_plogi_pyld->data, - &ha->plogi_els_payld.data, - sizeof(elsio->u.els_plogi.els_plogi_pyld->data)); + &ha->plogi_els_payld.fl_csp, LOGIN_TEMPLATE_SIZE); elsio->u.els_plogi.els_cmd = els_opcode; elsio->u.els_plogi.els_plogi_pyld->opcode = els_opcode; diff --git a/qla2x00t-32gbit/qla_mbx.c b/qla2x00t-32gbit/qla_mbx.c index 7bbbec59c..68f8797a8 100644 --- a/qla2x00t-32gbit/qla_mbx.c +++ b/qla2x00t-32gbit/qla_mbx.c @@ -4976,45 +4976,6 @@ qla25xx_set_els_cmds_supported(scsi_qla_host_t *vha) return rval; } -int -qla24xx_get_buffer_credits(scsi_qla_host_t *vha, struct buffer_credit_24xx *bbc, - dma_addr_t bbc_dma) -{ - mbx_cmd_t mc; - mbx_cmd_t *mcp = &mc; - int rval; - - if (!IS_FWI2_CAPABLE(vha->hw)) - return QLA_FUNCTION_FAILED; - - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x118e, - "Entered %s.\n", __func__); - - mcp->mb[0] = MBC_GET_RNID_PARAMS; - mcp->mb[1] = RNID_BUFFER_CREDITS << 8; - mcp->mb[2] = MSW(LSD(bbc_dma)); - mcp->mb[3] = LSW(LSD(bbc_dma)); - mcp->mb[6] = MSW(MSD(bbc_dma)); - mcp->mb[7] = LSW(MSD(bbc_dma)); - mcp->mb[8] = sizeof(*bbc) / sizeof(*bbc->parameter); - mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; - mcp->in_mb = MBX_1|MBX_0; - mcp->buf_size = sizeof(*bbc); - mcp->flags = MBX_DMA_IN; - mcp->tov = MBX_TOV_SECONDS; - rval = qla2x00_mailbox_command(vha, mcp); - - if (rval != QLA_SUCCESS) { - ql_dbg(ql_dbg_mbx, vha, 0x118f, - "Failed=%x mb[0]=%x,%x.\n", rval, mcp->mb[0], mcp->mb[1]); - } else { - ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1190, - "Done %s.\n", __func__); - } - - return rval; -} - static int qla2x00_read_asic_temperature(scsi_qla_host_t *vha, uint16_t *temp) { diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index e52a74b34..453c99c42 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -5888,12 +5888,10 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, dma_addr_t rsp_els_dma; dma_addr_t rsp_payload_dma; dma_addr_t stat_dma; - dma_addr_t bbc_dma; dma_addr_t sfp_dma; struct els_entry_24xx *rsp_els = NULL; struct rdp_rsp_payload *rsp_payload = NULL; struct link_statistics *stat = NULL; - struct buffer_credit_24xx *bbc = NULL; uint8_t *sfp = NULL; uint16_t sfp_flags = 0; uint rsp_payload_length = sizeof(*rsp_payload); @@ -5937,9 +5935,6 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, stat = dma_alloc_coherent(&ha->pdev->dev, sizeof(*stat), &stat_dma, GFP_KERNEL); - bbc = dma_alloc_coherent(&ha->pdev->dev, sizeof(*bbc), - &bbc_dma, GFP_KERNEL); - /* Prepare Response IOCB */ rsp_els->entry_type = ELS_IOCB_TYPE; rsp_els->entry_count = 1; @@ -6093,13 +6088,10 @@ void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, rsp_payload->buffer_credit_desc.attached_fcport_b2b = cpu_to_be32(0); rsp_payload->buffer_credit_desc.fcport_rtt = cpu_to_be32(0); - if (bbc) { - memset(bbc, 0, sizeof(*bbc)); - rval = qla24xx_get_buffer_credits(vha, bbc, bbc_dma); - if (!rval) { - rsp_payload->buffer_credit_desc.fcport_b2b = - cpu_to_be32(LSW(bbc->parameter[0])); - } + if (ha->flags.plogi_template_valid) { + uint32_t tmp = + be16_to_cpu(ha->plogi_els_payld.fl_csp.sp_bb_cred); + rsp_payload->buffer_credit_desc.fcport_b2b = cpu_to_be32(tmp); } if (rsp_payload_length < sizeof(*rsp_payload)) @@ -6277,9 +6269,6 @@ send: } dealloc: - if (bbc) - dma_free_coherent(&ha->pdev->dev, sizeof(*bbc), - bbc, bbc_dma); if (stat) dma_free_coherent(&ha->pdev->dev, sizeof(*stat), stat, stat_dma); From 6a5bbac38a6811d6a79788d0d89488470242c57e Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:01:40 +0000 Subject: [PATCH 25/56] qla2x00t-32gbit: Fix MPI reset needed message When printing the message: "MPI Heartbeat stop. MPI reset is not needed.." ..the wrong register was checked leading to always printing that MPI reset is not needed, even when it is needed. Fix the MPI reset message. Link: https://lore.kernel.org/r/20200929102152.32278-4-njavali@marvell.com Fixes: cbb01c2f2f63 ("scsi: qla2xxx: Fix MPI failure AEN (8200) handling") Cc: stable@vger.kernel.org Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit 7a6cdbd5e87515ebf6231b762ad903c7cff87b9c. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9271 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_isr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index 264e2a3ab..6d47b5e5b 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -778,7 +778,7 @@ qla27xx_handle_8200_aen(scsi_qla_host_t *vha, uint16_t *mb) ql_log(ql_log_warn, vha, 0x02f0, "MPI Heartbeat stop. MPI reset is%s needed. " "MB0[%xh] MB1[%xh] MB2[%xh] MB3[%xh]\n", - mb[0] & BIT_8 ? "" : " not", + mb[1] & BIT_8 ? "" : " not", mb[0], mb[1], mb[2], mb[3]); if ((mb[1] & BIT_8) == 0) From 71746d0d0f10a09e8da745920b5d14768fa99ddf Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:02:39 +0000 Subject: [PATCH 26/56] qla2x00t-32gbit: Fix reset of MPI firmware Normally, the MPI firmware is reset when an MPI dump is collected. If an unsaved MPI dump exists in the driver, though, an alternate mechanism is used. This mechanism, which was not fully correct, is not recommended and instead an MPI dump template walk is suggested to perform the MPI reset. To allow for the MPI dump template walk, extra space is reserved in the MPI dump buffer which gets used only when there is already an MPI dump in place. Link: https://lore.kernel.org/r/20200929102152.32278-5-njavali@marvell.com Fixes: cbb01c2f2f63 ("scsi: qla2xxx: Fix MPI failure AEN (8200) handling") Cc: stable@vger.kernel.org Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit 3e6efab865ac943f4ec43913eb665695737112b0. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9272 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_attr.c | 10 ++++++-- qla2x00t-32gbit/qla_gbl.h | 1 - qla2x00t-32gbit/qla_init.c | 2 ++ qla2x00t-32gbit/qla_tmpl.c | 49 ++++++++++---------------------------- 4 files changed, 23 insertions(+), 39 deletions(-) diff --git a/qla2x00t-32gbit/qla_attr.c b/qla2x00t-32gbit/qla_attr.c index c0c89ef3f..9e9a7869c 100644 --- a/qla2x00t-32gbit/qla_attr.c +++ b/qla2x00t-32gbit/qla_attr.c @@ -156,6 +156,14 @@ qla2x00_sysfs_write_fw_dump(struct file *filp, struct kobject *kobj, vha->host_no); } break; + case 10: + if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { + ql_log(ql_log_info, vha, 0x70e9, + "Issuing MPI firmware dump on host#%ld.\n", + vha->host_no); + ha->isp_ops->mpi_fw_dump(vha, 0); + } + break; } return count; } @@ -743,8 +751,6 @@ qla2x00_sysfs_write_reset(struct file *filp, struct kobject *kobj, qla83xx_idc_audit(vha, IDC_AUDIT_TIMESTAMP); qla83xx_idc_unlock(vha, 0); break; - } else if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { - qla27xx_reset_mpi(vha); } else { /* Make sure FC side is not in reset */ WARN_ON_ONCE(qla2x00_wait_for_hba_online(vha) != diff --git a/qla2x00t-32gbit/qla_gbl.h b/qla2x00t-32gbit/qla_gbl.h index 727a70a66..b7a112a4d 100644 --- a/qla2x00t-32gbit/qla_gbl.h +++ b/qla2x00t-32gbit/qla_gbl.h @@ -953,6 +953,5 @@ extern void qla2x00_dfs_remove_rport(scsi_qla_host_t *vha, struct fc_port *fp); /* nvme.c */ void qla_nvme_unregister_remote_port(struct fc_port *fcport); -void qla27xx_reset_mpi(scsi_qla_host_t *vha); void qla_handle_els_plogi_done(scsi_qla_host_t *vha, struct event_arg *ea); #endif /* _QLA_GBL_H */ diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 6e44ad80b..b80e2e4eb 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -3297,6 +3297,8 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha) j, fwdt->dump_size); dump_size += fwdt->dump_size; } + /* Add space for spare MPI fw dump. */ + dump_size += ha->fwdt[1].dump_size; } else { req_q_size = req->length * sizeof(request_t); rsp_q_size = rsp->length * sizeof(response_t); diff --git a/qla2x00t-32gbit/qla_tmpl.c b/qla2x00t-32gbit/qla_tmpl.c index 5273e3e9e..84f4416d3 100644 --- a/qla2x00t-32gbit/qla_tmpl.c +++ b/qla2x00t-32gbit/qla_tmpl.c @@ -11,33 +11,6 @@ #define IOBASE(vha) IOBAR(ISPREG(vha)) #define INVALID_ENTRY ((struct qla27xx_fwdt_entry *)0xffffffffffffffffUL) -/* hardware_lock assumed held. */ -static void -qla27xx_write_remote_reg(struct scsi_qla_host *vha, - u32 addr, u32 data) -{ - struct device_reg_24xx __iomem *reg = &vha->hw->iobase->isp24; - - ql_dbg(ql_dbg_misc, vha, 0xd300, - "%s: addr/data = %xh/%xh\n", __func__, addr, data); - - wrt_reg_dword(®->iobase_addr, 0x40); - wrt_reg_dword(®->iobase_c4, data); - wrt_reg_dword(®->iobase_window, addr); -} - -void -qla27xx_reset_mpi(scsi_qla_host_t *vha) -{ - ql_dbg(ql_dbg_misc + ql_dbg_verbose, vha, 0xd301, - "Entered %s.\n", __func__); - - qla27xx_write_remote_reg(vha, 0x104050, 0x40004); - qla27xx_write_remote_reg(vha, 0x10405c, 0x4); - - vha->hw->stat.num_mpi_reset++; -} - static inline void qla27xx_insert16(uint16_t value, void *buf, ulong *len) { @@ -1027,7 +1000,6 @@ void qla27xx_mpi_fwdump(scsi_qla_host_t *vha, int hardware_locked) { ulong flags = 0; - bool need_mpi_reset = true; #ifndef __CHECKER__ if (!hardware_locked) @@ -1035,14 +1007,20 @@ qla27xx_mpi_fwdump(scsi_qla_host_t *vha, int hardware_locked) #endif if (!vha->hw->mpi_fw_dump) { ql_log(ql_log_warn, vha, 0x02f3, "-> mpi_fwdump no buffer\n"); - } else if (vha->hw->mpi_fw_dumped) { - ql_log(ql_log_warn, vha, 0x02f4, - "-> MPI firmware already dumped (%p) -- ignoring request\n", - vha->hw->mpi_fw_dump); } else { struct fwdt *fwdt = &vha->hw->fwdt[1]; ulong len; void *buf = vha->hw->mpi_fw_dump; + bool walk_template_only = false; + + if (vha->hw->mpi_fw_dumped) { + /* Use the spare area for any further dumps. */ + buf += fwdt->dump_size; + walk_template_only = true; + ql_log(ql_log_warn, vha, 0x02f4, + "-> MPI firmware already dumped -- dump saving to temporary buffer %p.\n", + buf); + } ql_log(ql_log_warn, vha, 0x02f5, "-> fwdt1 running...\n"); if (!fwdt->template) { @@ -1057,9 +1035,10 @@ qla27xx_mpi_fwdump(scsi_qla_host_t *vha, int hardware_locked) ql_log(ql_log_warn, vha, 0x02f7, "-> fwdt1 fwdump residual=%+ld\n", fwdt->dump_size - len); - } else { - need_mpi_reset = false; } + vha->hw->stat.num_mpi_reset++; + if (walk_template_only) + goto bailout; vha->hw->mpi_fw_dump_len = len; vha->hw->mpi_fw_dumped = 1; @@ -1071,8 +1050,6 @@ qla27xx_mpi_fwdump(scsi_qla_host_t *vha, int hardware_locked) } bailout: - if (need_mpi_reset) - qla27xx_reset_mpi(vha); #ifndef __CHECKER__ if (!hardware_locked) spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); From 9a1b2c10e2521c9cab3867311406675df1935595 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:03:30 +0000 Subject: [PATCH 27/56] qla2x00t-32gbit: Fix crash on session cleanup with unload On unload, session cleanup prematurely gave the signal for driver unload path to advance. Link: https://lore.kernel.org/r/20200929102152.32278-6-njavali@marvell.com Fixes: 726b85487067 ("qla2xxx: Add framework for async fabric discovery") Cc: stable@vger.kernel.org Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit 50457dab670f396557e60c07f086358460876353. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9273 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_target.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index 21062e08c..04507e420 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -1246,14 +1246,15 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess) case DSC_DELETE_PEND: return; case DSC_DELETED: - if (tgt && tgt->tgt_stop && (tgt->sess_count == 0)) - wake_up_all(&tgt->waitQ); - if (sess->vha->fcport_count == 0) - wake_up_all(&sess->vha->fcport_waitQ); - if (!sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN] && - !sess->plogi_link[QLT_PLOGI_LINK_CONFLICT]) + !sess->plogi_link[QLT_PLOGI_LINK_CONFLICT]) { + if (tgt && tgt->tgt_stop && tgt->sess_count == 0) + wake_up_all(&tgt->waitQ); + + if (sess->vha->fcport_count == 0) + wake_up_all(&sess->vha->fcport_waitQ); return; + } break; case DSC_UPD_FCPORT: /* From 01a80a885196154df24296c52857cfbd871f9334 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:04:28 +0000 Subject: [PATCH 28/56] qla2x00t-32gbit: Fix point-to-point (N2N) device discovery issue Driver was using a shorter timeout waiting for PLOGI from the peer in point-to-point configurations. Some devices takes some time (~4 seconds) to initiate the PLOGI. This peer initiating PLOGI is when the peer has a higher P-WWN. Increase the wait time based on N2N R_A_TOV. Link: https://lore.kernel.org/r/20200929102152.32278-7-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit 94eda2717826015a80ca271394c4378747de8936. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9274 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 2 ++ qla2x00t-32gbit/qla_mbx.c | 3 ++- qla2x00t-32gbit/qla_os.c | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index 2bc052512..42455b9ef 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -5173,6 +5173,8 @@ struct sff_8247_a0 { ha->current_topology == ISP_CFG_N || \ !ha->current_topology) +#define QLA_N2N_WAIT_TIME 5 /* 2 * ra_tov(n2n) + 1 */ + #define NVME_TYPE(fcport) \ (fcport->fc4_type & FS_FC4TYPE_NVME) \ diff --git a/qla2x00t-32gbit/qla_mbx.c b/qla2x00t-32gbit/qla_mbx.c index 68f8797a8..07afd0d8a 100644 --- a/qla2x00t-32gbit/qla_mbx.c +++ b/qla2x00t-32gbit/qla_mbx.c @@ -3993,7 +3993,8 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, if (fcport) { fcport->plogi_nack_done_deadline = jiffies + HZ; - fcport->dm_login_expire = jiffies + 2*HZ; + fcport->dm_login_expire = jiffies + + QLA_N2N_WAIT_TIME * HZ; fcport->scan_state = QLA_FCPORT_FOUND; fcport->n2n_flag = 1; fcport->keep_nport_handle = 1; diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 453c99c42..4c3172253 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -5148,6 +5148,8 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e) fcport->fc4_type = e->u.new_sess.fc4_type; if (e->u.new_sess.fc4_type & FS_FCP_IS_N2N) { + fcport->dm_login_expire = jiffies + + QLA_N2N_WAIT_TIME * HZ; fcport->fc4_type = FS_FC4TYPE_FCP; fcport->n2n_flag = 1; if (vha->flags.nvme_enabled) From 480e079d69fb57d24353679456bfa6d474b14ee7 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:05:16 +0000 Subject: [PATCH 29/56] qla2x00t-32gbit: Update version to 10.02.00.103-k Link: https://lore.kernel.org/r/20200929102152.32278-8-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit 718c2fe92b208415fa76550975dc5d7708448f7c. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9275 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_version.h b/qla2x00t-32gbit/qla_version.h index d3205b52f..c2d4da52f 100644 --- a/qla2x00t-32gbit/qla_version.h +++ b/qla2x00t-32gbit/qla_version.h @@ -6,9 +6,9 @@ /* * Driver version */ -#define QLA2XXX_VERSION "10.02.00.102-k" +#define QLA2XXX_VERSION "10.02.00.103-k" #define QLA_DRIVER_MAJOR_VER 10 #define QLA_DRIVER_MINOR_VER 2 #define QLA_DRIVER_PATCH_VER 0 -#define QLA_DRIVER_BETA_VER 102 +#define QLA_DRIVER_BETA_VER 103 From 911051bdc2c523326e7212035cb21f79d63ec023 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:06:30 +0000 Subject: [PATCH 30/56] qla2x00t-32gbit: Fix inconsistent format argument type in qla_os.c Fix the following warnings: [drivers/scsi/qla2xxx/qla_os.c:4882]: (warning) %ld in format string (no. 2) requires 'long' but the argument type is 'unsigned long'. [drivers/scsi/qla2xxx/qla_os.c:5011]: (warning) %ld in format string (no. 1) requires 'long' but the argument type is 'unsigned long'. Link: https://lore.kernel.org/r/20200930022515.2862532-3-yebin10@huawei.com Reported-by: Hulk Robot Reviewed-by: Himanshu Madhani Reviewed-by: Nilesh Javali Signed-off-by: Ye Bin Signed-off-by: Martin K. Petersen See also upstream commit 250bd00923c72c846092271a9e51ee373db081b6. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9276 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 4c3172253..19886a55c 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -4927,7 +4927,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht, } INIT_DELAYED_WORK(&vha->scan.scan_work, qla_scan_work_fn); - sprintf(vha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, vha->host_no); + sprintf(vha->host_str, "%s_%lu", QLA2XXX_DRIVER_NAME, vha->host_no); ql_dbg(ql_dbg_init, vha, 0x0041, "Allocated the host=%p hw=%p vha=%p dev_name=%s", vha->host, vha->hw, vha, @@ -5056,7 +5056,7 @@ qla2x00_uevent_emit(struct scsi_qla_host *vha, u32 code) switch (code) { case QLA_UEVENT_CODE_FW_DUMP: - snprintf(event_string, sizeof(event_string), "FW_DUMP=%ld", + snprintf(event_string, sizeof(event_string), "FW_DUMP=%lu", vha->host_no); break; default: From 08aaacda29a72c57713d134c01fdb9cd21c02455 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:07:16 +0000 Subject: [PATCH 31/56] qla2x00t-32gbit: Fix inconsistent format argument type in qla_dbg.c Fix the following warning: [drivers/scsi/qla2xxx/qla_dbg.c:2451]: (warning) %ld in format string (no. 4) requires 'long' but the argument type is 'unsigned long'. Link: https://lore.kernel.org/r/20200930022515.2862532-4-yebin10@huawei.com Reported-by: Hulk Robot Reviewed-by: Himanshu Madhani Reviewed-by: Nilesh Javali Signed-off-by: Ye Bin Signed-off-by: Martin K. Petersen See also upstream commit 72e813d9a1b7a0a6dc6b27b563c389fbdb50cee2. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9277 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_dbg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_dbg.c b/qla2x00t-32gbit/qla_dbg.c index 1434789c9..bb7431912 100644 --- a/qla2x00t-32gbit/qla_dbg.c +++ b/qla2x00t-32gbit/qla_dbg.c @@ -2448,7 +2448,7 @@ static void ql_dbg_prefix(char *pbuf, int pbuf_size, const struct pci_dev *pdev = vha->hw->pdev; /* []-:: */ - snprintf(pbuf, pbuf_size, "%s [%s]-%04x:%ld: ", QL_MSGHDR, + snprintf(pbuf, pbuf_size, "%s [%s]-%04x:%lu: ", QL_MSGHDR, dev_name(&(pdev->dev)), msg_id, vha->host_no); } else { /* []-: : */ From f25d0e8996792eaf3f8205d0314abc891e50cfc4 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:08:08 +0000 Subject: [PATCH 32/56] qla2x00t-32gbit: Use constant when it is known Directly return constant when it is known to make code easier to understand. Link: https://lore.kernel.org/r/20200921112340.GA19336@duo.ucw.cz Reviewed-by: Himanshu Madhani Signed-off-by: Pavel Machek (CIP) Signed-off-by: Martin K. Petersen See also upstream commit b994718760fa6de431ee7504ca4553536c77ee43. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9278 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_nvme.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qla2x00t-32gbit/qla_nvme.c b/qla2x00t-32gbit/qla_nvme.c index fe4cf7cb8..9a0c99890 100644 --- a/qla2x00t-32gbit/qla_nvme.c +++ b/qla2x00t-32gbit/qla_nvme.c @@ -554,7 +554,7 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport, fc_port_t *fcport; struct srb_iocb *nvme; struct scsi_qla_host *vha; - int rval = -ENODEV; + int rval; srb_t *sp; struct qla_qpair *qpair = hw_queue_handle; struct nvme_private *priv = fd->private; @@ -562,14 +562,14 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport, if (!priv) { /* nvme association has been torn down */ - return rval; + return -ENODEV; } fcport = qla_rport->fcport; if (!qpair || !fcport || (qpair && !qpair->fw_started) || (fcport && fcport->deleted)) - return rval; + return -ENODEV; vha = fcport->vha; From ca0e0c811e282ac8cfa662763475d5350dcc7307 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:08:59 +0000 Subject: [PATCH 33/56] qla2x00t-32gbit: Do not consume srb greedily qla2xx_process_get_sp_from_handle() will clear the slot in which the current srb is stored. As a result it can't be used in qla24xx_process_mbx_iocb_response() to check for consistency and later again in qla24xx_mbx_iocb_entry(). Move the consistency check directly into qla24xx_mbx_iocb_entry() and avoid the double call or any open coding of the qla2xx_process_get_sp_from_handle() functionality. Link: https://lore.kernel.org/r/20200929073802.18770-1-dwagner@suse.de Fixes: 31a3271ff11b ("scsi: qla2xxx: Handle incorrect entry_type entries") Reviewed-by: Arun Easi Reviewed-by: Himanshu Madhani Signed-off-by: Daniel Wagner Signed-off-by: Martin K. Petersen See also upstream commit 657ed8a8a61b15eba70f7c4e2b61f643cf1ba91f. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9279 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_isr.c | 42 ++++++++++++++------------------------- 1 file changed, 15 insertions(+), 27 deletions(-) diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index 6d47b5e5b..636973bf7 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -1850,6 +1850,7 @@ qla24xx_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, struct mbx_24xx_entry *pkt) { const char func[] = "MBX-IOCB2"; + struct qla_hw_data *ha = vha->hw; srb_t *sp; struct srb_iocb *si; u16 sz, i; @@ -1859,6 +1860,18 @@ qla24xx_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, if (!sp) return; + if (sp->type == SRB_SCSI_CMD || + sp->type == SRB_NVME_CMD || + sp->type == SRB_TM_CMD) { + ql_log(ql_log_warn, vha, 0x509d, + "Inconsistent event entry type %d\n", sp->type); + if (IS_P3P_TYPE(ha)) + set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags); + else + set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); + return; + } + si = &sp->u.iocb_cmd; sz = min(ARRAY_SIZE(pkt->mb), ARRAY_SIZE(sp->u.iocb_cmd.u.mbx.in_mb)); @@ -3434,32 +3447,6 @@ void qla24xx_nvme_ls4_iocb(struct scsi_qla_host *vha, sp->done(sp, comp_status); } -static void qla24xx_process_mbx_iocb_response(struct scsi_qla_host *vha, - struct rsp_que *rsp, struct sts_entry_24xx *pkt) -{ - struct qla_hw_data *ha = vha->hw; - srb_t *sp; - static const char func[] = "MBX-IOCB2"; - - sp = qla2x00_get_sp_from_handle(vha, func, rsp->req, pkt); - if (!sp) - return; - - if (sp->type == SRB_SCSI_CMD || - sp->type == SRB_NVME_CMD || - sp->type == SRB_TM_CMD) { - ql_log(ql_log_warn, vha, 0x509d, - "Inconsistent event entry type %d\n", sp->type); - if (IS_P3P_TYPE(ha)) - set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags); - else - set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); - return; - } - - qla24xx_mbx_iocb_entry(vha, rsp->req, (struct mbx_24xx_entry *)pkt); -} - /** * qla24xx_process_response_queue() - Process response queue entries. * @vha: SCSI driver HA context @@ -3570,7 +3557,8 @@ process_err: (struct abort_entry_24xx *)pkt); break; case MBX_IOCB_TYPE: - qla24xx_process_mbx_iocb_response(vha, rsp, pkt); + qla24xx_mbx_iocb_entry(vha, rsp->req, + (struct mbx_24xx_entry *)pkt); break; case VP_CTRL_IOCB_TYPE: qla_ctrlvp_completed(vha, rsp->req, From 847600bbbae4a2851f9f30daa81c25e99f7be876 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:09:46 +0000 Subject: [PATCH 34/56] qla2x00t-32gbit: Initialize variable in qla8044_poll_reg() clang static analysis reports this problem: qla_nx2.c:694:3: warning: 6th function call argument is an uninitialized value ql_log(ql_log_fatal, vha, 0xb090, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In qla8044_poll_reg(), when reading the reg fails, the error is reported by reusing the timeout error reporter. Because the value is unset, a garbage value will be reported. Initialize the value. Link: https://lore.kernel.org/r/20201005144544.25335-1-trix@redhat.com Reviewed-by: Himanshu Madhani Signed-off-by: Tom Rix Signed-off-by: Martin K. Petersen See also upstream commit 21a6cd48bb483e16703f4e4415ad2e9e3c71a5dd. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9280 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_nx2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_nx2.c b/qla2x00t-32gbit/qla_nx2.c index 3a415b12d..01ccd4526 100644 --- a/qla2x00t-32gbit/qla_nx2.c +++ b/qla2x00t-32gbit/qla_nx2.c @@ -659,7 +659,7 @@ static int qla8044_poll_reg(struct scsi_qla_host *vha, uint32_t addr, int duration, uint32_t test_mask, uint32_t test_result) { - uint32_t value; + uint32_t value = 0; int timeout_error; uint8_t retries; int ret_val = QLA_SUCCESS; From 0b29c0e5d83c0d55931478c11ef46f9114111561 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:10:25 +0000 Subject: [PATCH 35/56] qla2x00t-32gbit: Convert to DEFINE_SHOW_ATTRIBUTE Use DEFINE_SHOW_ATTRIBUTE macro to simplify the code. Link: https://lore.kernel.org/r/20200919025202.17531-1-miaoqinglang@huawei.com Reviewed-by: Himanshu Madhani Acked-by: Arun Easi Signed-off-by: Qinglang Miao Signed-off-by: Martin K. Petersen See also upstream commit 5e7e6472eda90433b251566755533cf1e9c2e522. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9281 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_dfs.c | 68 +++++---------------------------------- 1 file changed, 8 insertions(+), 60 deletions(-) diff --git a/qla2x00t-32gbit/qla_dfs.c b/qla2x00t-32gbit/qla_dfs.c index f89ad3274..d5ebcf7d7 100644 --- a/qla2x00t-32gbit/qla_dfs.c +++ b/qla2x00t-32gbit/qla_dfs.c @@ -170,20 +170,7 @@ qla2x00_dfs_tgt_sess_show(struct seq_file *s, void *unused) return 0; } -static int -qla2x00_dfs_tgt_sess_open(struct inode *inode, struct file *file) -{ - scsi_qla_host_t *vha = inode->i_private; - - return single_open(file, qla2x00_dfs_tgt_sess_show, vha); -} - -static const struct file_operations dfs_tgt_sess_ops = { - .open = qla2x00_dfs_tgt_sess_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(qla2x00_dfs_tgt_sess); static int qla2x00_dfs_tgt_port_database_show(struct seq_file *s, void *unused) @@ -239,20 +226,7 @@ out_free_id_list: return 0; } -static int -qla2x00_dfs_tgt_port_database_open(struct inode *inode, struct file *file) -{ - scsi_qla_host_t *vha = inode->i_private; - - return single_open(file, qla2x00_dfs_tgt_port_database_show, vha); -} - -static const struct file_operations dfs_tgt_port_database_ops = { - .open = qla2x00_dfs_tgt_port_database_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(qla2x00_dfs_tgt_port_database); static int qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused) @@ -301,20 +275,7 @@ qla_dfs_fw_resource_cnt_show(struct seq_file *s, void *unused) return 0; } -static int -qla_dfs_fw_resource_cnt_open(struct inode *inode, struct file *file) -{ - struct scsi_qla_host *vha = inode->i_private; - - return single_open(file, qla_dfs_fw_resource_cnt_show, vha); -} - -static const struct file_operations dfs_fw_resource_cnt_ops = { - .open = qla_dfs_fw_resource_cnt_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(qla_dfs_fw_resource_cnt); static int qla_dfs_tgt_counters_show(struct seq_file *s, void *unused) @@ -391,20 +352,7 @@ qla_dfs_tgt_counters_show(struct seq_file *s, void *unused) return 0; } -static int -qla_dfs_tgt_counters_open(struct inode *inode, struct file *file) -{ - struct scsi_qla_host *vha = inode->i_private; - - return single_open(file, qla_dfs_tgt_counters_show, vha); -} - -static const struct file_operations dfs_tgt_counters_ops = { - .open = qla_dfs_tgt_counters_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(qla_dfs_tgt_counters); static int qla2x00_dfs_fce_show(struct seq_file *s, void *unused) @@ -606,19 +554,19 @@ create_dir: create_nodes: ha->dfs_fw_resource_cnt = debugfs_create_file("fw_resource_count", - S_IRUSR, ha->dfs_dir, vha, &dfs_fw_resource_cnt_ops); + S_IRUSR, ha->dfs_dir, vha, &qla_dfs_fw_resource_cnt_fops); ha->dfs_tgt_counters = debugfs_create_file("tgt_counters", S_IRUSR, - ha->dfs_dir, vha, &dfs_tgt_counters_ops); + ha->dfs_dir, vha, &qla_dfs_tgt_counters_fops); ha->tgt.dfs_tgt_port_database = debugfs_create_file("tgt_port_database", - S_IRUSR, ha->dfs_dir, vha, &dfs_tgt_port_database_ops); + S_IRUSR, ha->dfs_dir, vha, &qla2x00_dfs_tgt_port_database_fops); ha->dfs_fce = debugfs_create_file("fce", S_IRUSR, ha->dfs_dir, vha, &dfs_fce_ops); ha->tgt.dfs_tgt_sess = debugfs_create_file("tgt_sess", - S_IRUSR, ha->dfs_dir, vha, &dfs_tgt_sess_ops); + S_IRUSR, ha->dfs_dir, vha, &qla2x00_dfs_tgt_sess_fops); if (IS_QLA27XX(ha) || IS_QLA83XX(ha) || IS_QLA28XX(ha)) { ha->tgt.dfs_naqp = debugfs_create_file("naqp", From ca057f9e48a82281910eabd9c077075ee2645b55 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:12:34 +0000 Subject: [PATCH 36/56] qla2x00t-32gbit: Fix return of uninitialized value in rval A previous change removed the initialization of rval and there is now an error where an uninitialized rval is being returned on an error return path. Fix this by returning -ENODEV. Link: https://lore.kernel.org/r/20201008183239.200358-1-colin.king@canonical.com Fixes: b994718760fa ("scsi: qla2xxx: Use constant when it is known") Reviewed-by: Himanshu Madhani Acked-by: Pavel Machek (CIP) Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen Addresses-Coverity: ("Uninitialized scalar variable") See also upstream commit 1ef16a407f544408d3559e4de2ed05591df4da75. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9282 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_nvme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_nvme.c b/qla2x00t-32gbit/qla_nvme.c index 9a0c99890..6ceb718c4 100644 --- a/qla2x00t-32gbit/qla_nvme.c +++ b/qla2x00t-32gbit/qla_nvme.c @@ -574,7 +574,7 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport, vha = fcport->vha; if (!(fcport->nvme_flag & NVME_FLAG_REGISTERED)) - return rval; + return -ENODEV; if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) || (qpair && !qpair->fw_started) || fcport->deleted) From 9c90f88f1d5ed0c3975922f1855ccdd12c681d62 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:13:42 +0000 Subject: [PATCH 37/56] qla2x00t-32gbit: Return EBUSY on fcport deletion When the fcport is about to be deleted we should return EBUSY instead of ENODEV. Only for EBUSY will the request be requeued in a multipath setup. Also return EBUSY when the firmware has not yet started to avoid dropping the request. Link: https://lore.kernel.org/r/20201014073048.36219-1-dwagner@suse.de Reviewed-by: Arun Easi Signed-off-by: Daniel Wagner Signed-off-by: Martin K. Petersen See also upstream commit 98f9d33c5d0d779e6c96a4a8ac995085b11924f0. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9283 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_nvme.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_nvme.c b/qla2x00t-32gbit/qla_nvme.c index 6ceb718c4..aac984c76 100644 --- a/qla2x00t-32gbit/qla_nvme.c +++ b/qla2x00t-32gbit/qla_nvme.c @@ -567,10 +567,12 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport, fcport = qla_rport->fcport; - if (!qpair || !fcport || (qpair && !qpair->fw_started) || - (fcport && fcport->deleted)) + if (!qpair || !fcport) return -ENODEV; + if (!qpair->fw_started || fcport->deleted) + return -EBUSY; + vha = fcport->vha; if (!(fcport->nvme_flag & NVME_FLAG_REGISTERED)) From c734b8e0d0fb70f196d626ca8e58d80c37acc268 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:14:29 +0000 Subject: [PATCH 38/56] qla2x00t-32gbit: Remove unneeded break statements A break is not needed if it is preceded by a return or goto. Link: https://lore.kernel.org/r/20201019142333.16584-1-trix@redhat.com Signed-off-by: Tom Rix Signed-off-by: Martin K. Petersen See also upstream commit 170b7d2de29e6239b8dbc63a88de1fa9789b0d8d. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9284 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_mbx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_mbx.c b/qla2x00t-32gbit/qla_mbx.c index 07afd0d8a..40af7f152 100644 --- a/qla2x00t-32gbit/qla_mbx.c +++ b/qla2x00t-32gbit/qla_mbx.c @@ -4030,7 +4030,6 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags); return; - break; case TOPO_FL: ha->current_topology = ISP_CFG_FL; break; From be4657525b4ca1a0845116318489c5baa222abbd Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:20:19 +0000 Subject: [PATCH 39/56] qla2x00t-32gbit: remove incorrect sparse #ifdef The code to try to shut up sparse warnings about questionable locking didn't shut up sparse: it made the result not parse as valid C at all, since the end result now has a label with no statement. The proper fix is to just always lock the hardware, the same way Bart did in commit 8ae178760b23 ("scsi: qla2xxx: Simplify the functions for dumping firmware"). That avoids the whole problem with having locking that is not statically obvious. But in the meantime, just remove the incorrect attempt at trying to avoid a sparse warning that just made things worse. This was exposed by commit 3e6efab865ac ("scsi: qla2xxx: Fix reset of MPI firmware"), very similarly to how commit cbb01c2f2f63 ("scsi: qla2xxx: Fix MPI failure AEN (8200) handling") exposed the same problem in another place, and caused that commit 8ae178760b23. Please don't add code to just shut up sparse without actually fixing what sparse complains about. Reported-by: Luc Van Oostenryck Cc: Bart Van Assche Cc: Arun Easi Signed-off-by: Linus Torvalds See also upstream commit 4525c8781ec0701ce824e8bd379ae1b129e26568. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9285 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_tmpl.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/qla2x00t-32gbit/qla_tmpl.c b/qla2x00t-32gbit/qla_tmpl.c index 84f4416d3..bd8623ee1 100644 --- a/qla2x00t-32gbit/qla_tmpl.c +++ b/qla2x00t-32gbit/qla_tmpl.c @@ -1001,10 +1001,8 @@ qla27xx_mpi_fwdump(scsi_qla_host_t *vha, int hardware_locked) { ulong flags = 0; -#ifndef __CHECKER__ if (!hardware_locked) spin_lock_irqsave(&vha->hw->hardware_lock, flags); -#endif if (!vha->hw->mpi_fw_dump) { ql_log(ql_log_warn, vha, 0x02f3, "-> mpi_fwdump no buffer\n"); } else { @@ -1050,10 +1048,8 @@ qla27xx_mpi_fwdump(scsi_qla_host_t *vha, int hardware_locked) } bailout: -#ifndef __CHECKER__ if (!hardware_locked) spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); -#endif } void From ab09b4f3c3f3dbd228d6f07a2a81b8c7912426d2 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:24:14 +0000 Subject: [PATCH 40/56] qla2x00t-32gbit: Drop TARGET_SCF_LOOKUP_LUN_FROM_TAG Only the __qlt_24xx_handle_abts() code path does not know the LUN for an abort and it uses the TARGET_SCF_LOOKUP_LUN_FROM_TAG flag to have LIO core look it up. LIO uses target_lookup_lun_from_tag to go from cmd tag to LUN for the driver. However, qla2xxx has a tcm_qla2xxx_find_cmd_by_tag() which does almost the same thing as the LIO helper (it finds the cmd but does not return the LUN). This patch has qla2xxx use its internal helper. Link: https://lore.kernel.org/r/1604257174-4524-4-git-send-email-michael.christie@oracle.com Cc: Nilesh Javali Reviewed-by: Himanshu Madhani Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen See also upstream commit 8f394da36a361cbe0e1e8b1d4213e5598c8095ac. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9286 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_target.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index 04507e420..770f1abdd 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -2098,6 +2098,7 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha, struct qla_hw_data *ha = vha->hw; struct qla_tgt_mgmt_cmd *mcmd; struct qla_qpair_hint *h = &vha->vha_tgt.qla_tgt->qphints[0]; + struct qla_tgt_cmd *abort_cmd; ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00f, "qla_target(%d): task abort (tag=%d)\n", @@ -2127,21 +2128,19 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha, mcmd->se_cmd.cpuid = h->cpuid; #endif - if (ha->tgt.tgt_ops->find_cmd_by_tag) { - struct qla_tgt_cmd *abort_cmd; - - abort_cmd = ha->tgt.tgt_ops->find_cmd_by_tag(sess, - le32_to_cpu(abts->exchange_addr_to_abort)); - if (abort_cmd && abort_cmd->qpair) { - mcmd->qpair = abort_cmd->qpair; -#if HAVE_SE_CMD_CPUID - mcmd->se_cmd.cpuid = abort_cmd->se_cmd.cpuid; -#endif - mcmd->abort_io_attr = abort_cmd->atio.u.isp24.attr; - mcmd->flags = QLA24XX_MGMT_ABORT_IO_ATTR_VALID; - } - } + abort_cmd = ha->tgt.tgt_ops->find_cmd_by_tag(sess, + le32_to_cpu(abts->exchange_addr_to_abort)); + if (!abort_cmd) + return -EIO; + mcmd->unpacked_lun = abort_cmd->se_cmd.orig_fe_lun; + if (abort_cmd->qpair) { + mcmd->qpair = abort_cmd->qpair; + mcmd->se_cmd.cpuid = abort_cmd->se_cmd.cpuid; + mcmd->abort_io_attr = abort_cmd->atio.u.isp24.attr; + mcmd->flags = QLA24XX_MGMT_ABORT_IO_ATTR_VALID; + } + INIT_WORK(&mcmd->work, qlt_do_tmr_work); #if HAVE_SE_CMD_CPUID queue_work_on(mcmd->se_cmd.cpuid, qla_tgt_wq, &mcmd->work); From 7579ad898047cbaa0aff612f97eba05a582afe54 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:28:43 +0000 Subject: [PATCH 41/56] qla2x00t-32gbit: Move sess cmd list/lock to driver Except for debug output in the shutdown path, tcm_qla2xxx is the only driver using the se_session sess_cmd_list. Move the list to that driver to facilitate removing the sess_cmd_lock from the main I/O path for the rest of the drivers. Link: https://lore.kernel.org/r/1604257174-4524-6-git-send-email-michael.christie@oracle.com Cc: Nilesh Javali Reviewed-by: Himanshu Madhani Signed-off-by: Mike Christie Signed-off-by: Martin K. Petersen See also upstream commit 605e74025f953b995a3a241ead43bde71c1c99b5. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9287 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 2 ++ qla2x00t-32gbit/qla_init.c | 3 +++ qla2x00t-32gbit/qla_target.c | 1 + qla2x00t-32gbit/qla_target.h | 1 + 4 files changed, 7 insertions(+) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index 42455b9ef..ed21cc57e 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -2519,6 +2519,8 @@ typedef struct fc_port { int generation; struct se_session *se_sess; + struct list_head sess_cmd_list; + spinlock_t sess_cmd_lock; struct kref sess_kref; struct qla_tgt *tgt; unsigned long expires; diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index b80e2e4eb..56b201b9f 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -4974,6 +4974,9 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags) INIT_LIST_HEAD(&fcport->gnl_entry); INIT_LIST_HEAD(&fcport->list); + INIT_LIST_HEAD(&fcport->sess_cmd_list); + spin_lock_init(&fcport->sess_cmd_lock); + return fcport; } diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index 770f1abdd..a07bde90f 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -4342,6 +4342,7 @@ static struct qla_tgt_cmd *qlt_get_tag(scsi_qla_host_t *vha, cmd->cmd_type = TYPE_TGT_CMD; memcpy(&cmd->atio, atio, sizeof(*atio)); + INIT_LIST_HEAD(&cmd->sess_cmd_list); cmd->state = QLA_TGT_STATE_NEW; cmd->tgt = vha->vha_tgt.qla_tgt; qlt_incr_num_pend_cmds(vha); diff --git a/qla2x00t-32gbit/qla_target.h b/qla2x00t-32gbit/qla_target.h index f696ffb21..8afdc4b64 100644 --- a/qla2x00t-32gbit/qla_target.h +++ b/qla2x00t-32gbit/qla_target.h @@ -891,6 +891,7 @@ struct qla_tgt_cmd { uint8_t cmd_type; uint8_t pad[7]; struct se_cmd se_cmd; + struct list_head sess_cmd_list; struct scst_cmd *scst_cmd; #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 12, 0) /* From bb82ef36cc6a83ea2634d535a82ec7a5c0a58ae0 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:31:01 +0000 Subject: [PATCH 42/56] qla2x00t-32gbit: Remove in_interrupt() from qla82xx-specific code qla82xx_idc_lock() spins on a certain hardware state until it's updated. At the end of each spin, if in_interrupt() is true, it does 20 loops of cpu_relax(). Otherwise, it yields the CPU. While in_interrupt() is ill-defined and does not provide what the name suggests, it is not needed here: qla82xx_idc_lock() is always called from process context. Below is an analysis of its callers, in order of appearance: - qla_nx.c: qla82xx_device_bootstrap(), only called by qla82xx_device_state_handler(), has multiple msleep()s. - qla_nx.c: qla82xx_need_qsnt_handler(), has one second msleep() - qla_nx.c: qla82xx_wait_for_state_change(), one second msleep() - qla_nx.c: qla82xx_need_reset_handler(), can sleep up to 10 seconds - qla_nx.c: qla82xx_device_state_handler(), has multiple msleep()s - qla_nx.c: qla82xx_abort_isp(), if it's a qla82xx controller, calls qla82xx_device_state_handler(), which sleeps. It's also bound to isp_operations ->abort_isp() hook, where all the callers are in process context. - qla_nx.c: qla82xx_beacon_on(), bound to isp_operations ->beacon_on() hook. That hook is only called once, in a mutex locked context, from qla2x00_beacon_store(). - qla_nx.c: qla82xx_beacon_off(), bound to isp_operations ->beacon_off() hook. Like ->beacon_on(), it's only called once, in a mutex locked context, from qla2x00_beacon_store(). - qla_nx.c: qla82xx_fw_dump(), calls qla2x00_wait_for_chip_reset(), which has msleep() in a loop. It is bound to isp_operations ->fw_dump() hook. That hook *is* called from atomic context at qla_isr.c by multiple interrupt handlers. Nonetheless, it's other controllers interrupt handlers, and not the qla82xx. - qla82xx_msix_default() and qla82xx_msix_rsp_q() call qla24xx_process_response_queue() which doesn't implement the firmware dumping. - qla_attr.c: qla2x00_sysfs_write_fw_dump(), and qla2x00_sysfs_write_reset(), process-context sysfs ->write() hooks. - qla_os.c: qla2x00_probe_one(). PCI ->probe(), process context. - qla_os.c: qla2x00_clear_drv_active(), called solely from qla2x00_remove_one(), which is PCI ->remove() hook, process context. - qla_os.c: qla2x00_do_dpc(), kthread function, process context. Remove the in_interrupt() check. Change qla82xx_idc_lock() specification to a purely process-context function. Mark it with "Context: task, might sleep". Change qla82xx_idc_lock() implementation to sleep 100ms, instead of a schedule(), for each spin. This is more deterministic, and it matches the other qla models idc_lock() functions. Link: https://lore.kernel.org/r/20201126132952.2287996-5-bigeasy@linutronix.de Cc: Nilesh Javali Cc: Reviewed-by: Himanshu Madhani Reviewed-by: Daniel Wagner Signed-off-by: Ahmed S. Darwish Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Martin K. Petersen See also upstream commit 8ac246bdd07a0f948f0e33eb4797bd2645cd8224. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9288 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 5 +++++ qla2x00t-32gbit/qla_nx.c | 25 +++++++++++-------------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index ed21cc57e..f63a952f0 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -3323,8 +3323,10 @@ struct isp_operations { void (*fw_dump)(struct scsi_qla_host *vha); void (*mpi_fw_dump)(struct scsi_qla_host *, int); + /* Context: task, might sleep */ int (*beacon_on) (struct scsi_qla_host *); int (*beacon_off) (struct scsi_qla_host *); + void (*beacon_blink) (struct scsi_qla_host *); void *(*read_optrom)(struct scsi_qla_host *, void *, @@ -3335,7 +3337,10 @@ struct isp_operations { int (*get_flash_version) (struct scsi_qla_host *, void *); int (*start_scsi) (srb_t *); int (*start_scsi_mq) (srb_t *); + + /* Context: task, might sleep */ int (*abort_isp) (struct scsi_qla_host *); + int (*iospace_config)(struct qla_hw_data *); int (*initialize_adapter)(struct scsi_qla_host *); }; diff --git a/qla2x00t-32gbit/qla_nx.c b/qla2x00t-32gbit/qla_nx.c index 7e45a0b94..d38bc3f3a 100644 --- a/qla2x00t-32gbit/qla_nx.c +++ b/qla2x00t-32gbit/qla_nx.c @@ -488,29 +488,26 @@ qla82xx_rd_32(struct qla_hw_data *ha, ulong off_in) return data; } -#define IDC_LOCK_TIMEOUT 100000000 +/* + * Context: task, might sleep + */ int qla82xx_idc_lock(struct qla_hw_data *ha) { - int i; - int done = 0, timeout = 0; + const int delay_ms = 100, timeout_ms = 2000; + int done, total = 0; - while (!done) { + might_sleep(); + + while (true) { /* acquire semaphore5 from PCI HW block */ done = qla82xx_rd_32(ha, QLA82XX_PCIE_REG(PCIE_SEM5_LOCK)); if (done == 1) break; - if (timeout >= IDC_LOCK_TIMEOUT) + if (WARN_ON_ONCE(total >= timeout_ms)) return -1; - timeout++; - - /* Yield CPU */ - if (!in_interrupt()) - schedule(); - else { - for (i = 0; i < 20; i++) - cpu_relax(); - } + total += delay_ms; + msleep(delay_ms); } return 0; From d2f8ac98c0aea5d2fc3b16b559b5570f73cb095f Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:35:00 +0000 Subject: [PATCH 43/56] qla2x00t-32gbit: Remove in_interrupt() from qla83xx-specific code qla83xx_wait_logic() is used to control the frequency of device IDC lock retries. If in_interrupt() is true, it does 20 loops of cpu_relax(). Otherwise, it sleeps for 100ms and yields the CPU. While in_interrupt() is ill-defined and does not provide what the name suggests, it is not needed here: that qla83xx_wait_logic() is exclusively called by qla83xx_idc_lock() / unlock(), and they always run from process context. Below is an analysis of all the idc lock/unlock callers, in order of appearance: - qla_os.c: qla83xx_nic_core_unrecoverable_work(), qla83xx_idc_state_handler_work(), qla83xx_nic_core_reset_work(), qla83xx_service_idc_aen(), all workqueue context - qla_os.c: qla83xx_check_nic_core_fw_alive(), has msleep() - qla_os.c: qla83xx_set_drv_presence(), called once from qla2x00_abort_isp(), which is bound to process-context ->abort_isp() hook. It also invokes wait_for_completion_timeout() through the chain qla2x00_configure_hba() => qla24xx_link_initialize() => qla2x00_mailbox_command(). - qla_os.c: qla83xx_clear_drv_presence(), which is called from qla2x00_abort_isp() discussed above, and from qla2x00_remove_one() which is PCI process-context ->remove() hook. - qla_os.c: qla83xx_need_reset_handler(), has a one second msleep() in a loop. - qla_os.c: qla83xx_device_bootstrap(), called only by qla83xx_idc_state_handler(), which has multiple msleep() invocations. - qla_os.c: qla83xx_idc_state_handler(), multiple msleep() invocations. - qla_attr.c: qla2x00_sysfs_write_reset(), sysfs bin_attribute ->write() hook, process context - qla_init.c: qla83xx_nic_core_fw_load() => qla_init.c: qla2x00_initialize_adapter() => bound to isp_operations ->initialize_adapter() hook ** => qla_os.c: qla2x00_probe_one(), PCI ->probe() process ctx - qla_init.c: qla83xx_initiating_reset(), msleep() in a loop. - qla_init.c: qla83xx_nic_core_reset(), called by qla83xx_nic_core_reset_work(), workqueue context. Remove the in_interrupt() check, and thus replace the entirety of qla83xx_wait_logic() with an msleep(QLA83XX_WAIT_LOGIC_MS). Mark qla83xx_idc_lock() / unlock() with "Context: task, can sleep". Link: https://lore.kernel.org/r/20201126132952.2287996-7-bigeasy@linutronix.de Cc: Nilesh Javali Cc: GR-QLogic-Storage-Upstream@marvell.com Reviewed-by: Himanshu Madhani Reviewed-by: Daniel Wagner Signed-off-by: Ahmed S. Darwish Signed-off-by: Sebastian Andrzej Siewior Signed-off-by: Martin K. Petersen See also upstream commit 4f6a57c23b1e002487159791feef7d54b725bfa6. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9289 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 43 ++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 19886a55c..737d01eae 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -5671,25 +5671,10 @@ qla83xx_service_idc_aen(struct work_struct *work) } } -static void -qla83xx_wait_logic(void) -{ - int i; - - /* Yield CPU */ - if (!in_interrupt()) { - /* - * Wait about 200ms before retrying again. - * This controls the number of retries for single - * lock operation. - */ - msleep(100); - schedule(); - } else { - for (i = 0; i < 20; i++) - cpu_relax(); /* This a nop instr on i386 */ - } -} +/* + * Control the frequency of IDC lock retries + */ +#define QLA83XX_WAIT_LOGIC_MS 100 static int qla83xx_force_lock_recovery(scsi_qla_host_t *base_vha) @@ -5779,7 +5764,7 @@ retry_lockid: goto exit; if (o_drv_lockid == n_drv_lockid) { - qla83xx_wait_logic(); + msleep(QLA83XX_WAIT_LOGIC_MS); goto retry_lockid; } else return QLA_SUCCESS; @@ -5788,6 +5773,9 @@ exit: return rval; } +/* + * Context: task, can sleep + */ void qla83xx_idc_lock(scsi_qla_host_t *base_vha, uint16_t requester_id) { @@ -5795,6 +5783,8 @@ qla83xx_idc_lock(scsi_qla_host_t *base_vha, uint16_t requester_id) uint32_t lock_owner; struct qla_hw_data *ha = base_vha->hw; + might_sleep(); + /* IDC-lock implementation using driver-lock/lock-id remote registers */ retry_lock: if (qla83xx_rd_reg(base_vha, QLA83XX_DRIVER_LOCK, &data) @@ -5813,7 +5803,7 @@ retry_lock: /* Retry/Perform IDC-Lock recovery */ if (qla83xx_idc_lock_recovery(base_vha) == QLA_SUCCESS) { - qla83xx_wait_logic(); + msleep(QLA83XX_WAIT_LOGIC_MS); goto retry_lock; } else ql_log(ql_log_warn, base_vha, 0xb075, @@ -6311,6 +6301,9 @@ void qla24xx_process_purex_list(struct purex_list *list) } } +/* + * Context: task, can sleep + */ void qla83xx_idc_unlock(scsi_qla_host_t *base_vha, uint16_t requester_id) { @@ -6321,6 +6314,8 @@ qla83xx_idc_unlock(scsi_qla_host_t *base_vha, uint16_t requester_id) uint32_t data; struct qla_hw_data *ha = base_vha->hw; + might_sleep(); + /* IDC-unlock implementation using driver-unlock/lock-id * remote registers */ @@ -6336,7 +6331,7 @@ retry_unlock: /* SV: XXX: IDC unlock retrying needed here? */ /* Retry for IDC-unlock */ - qla83xx_wait_logic(); + msleep(QLA83XX_WAIT_LOGIC_MS); retry++; ql_dbg(ql_dbg_p3p, base_vha, 0xb064, "Failed to release IDC lock, retrying=%d\n", retry); @@ -6344,7 +6339,7 @@ retry_unlock: } } else if (retry < 10) { /* Retry for IDC-unlock */ - qla83xx_wait_logic(); + msleep(QLA83XX_WAIT_LOGIC_MS); retry++; ql_dbg(ql_dbg_p3p, base_vha, 0xb065, "Failed to read drv-lockid, retrying=%d\n", retry); @@ -6360,7 +6355,7 @@ retry_unlock2: if (qla83xx_access_control(base_vha, options, 0, 0, NULL)) { if (retry < 10) { /* Retry for IDC-unlock */ - qla83xx_wait_logic(); + msleep(QLA83XX_WAIT_LOGIC_MS); retry++; ql_dbg(ql_dbg_p3p, base_vha, 0xb066, "Failed to release IDC lock, retrying=%d\n", retry); From d43dc69e2722633944229462c809162556b68b1f Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:35:42 +0000 Subject: [PATCH 44/56] qla2x00t-32gbit: Remove trailing semicolon in macro definition The macro use will already have a semicolon. Remove unneeded escaped newline. Link: https://lore.kernel.org/r/20201130205509.3447316-1-trix@redhat.com Reviewed-by: Daniel Wagner Signed-off-by: Tom Rix Signed-off-by: Martin K. Petersen See also upstream commit 8f525bc2a7b296cf24cfa7e5186bc32dd8e766aa. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9290 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index f63a952f0..ea4011440 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -5002,8 +5002,7 @@ struct secure_flash_update_block_pk { } while (0) #define QLA_QPAIR_MARK_NOT_BUSY(__qpair) \ - atomic_dec(&__qpair->ref_count); \ - + atomic_dec(&__qpair->ref_count) #define QLA_ENA_CONF(_ha) {\ int i;\ From 590980405f3c1986ef258af506260043f079a141 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:37:18 +0000 Subject: [PATCH 45/56] qla2x00t-32gbit: Change post del message from debug level to log level Change the message debug level. Link: https://lore.kernel.org/r/20201202132312.19966-3-njavali@marvell.com Signed-off-by: Saurav Kashyap Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit c1599657d48ca65861408f9264e12c050ac9626b. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9291 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_gs.c | 8 ++++---- qla2x00t-32gbit/qla_target.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/qla2x00t-32gbit/qla_gs.c b/qla2x00t-32gbit/qla_gs.c index e28c4b7ec..391ac75e3 100644 --- a/qla2x00t-32gbit/qla_gs.c +++ b/qla2x00t-32gbit/qla_gs.c @@ -3558,10 +3558,10 @@ login_logout: if (fcport->flags & FCF_FCP2_DEVICE) fcport->logout_on_delete = 0; - ql_dbg(ql_dbg_disc, vha, 0x20f0, - "%s %d %8phC post del sess\n", - __func__, __LINE__, - fcport->port_name); + ql_log(ql_log_warn, vha, 0x20f0, + "%s %d %8phC post del sess\n", + __func__, __LINE__, + fcport->port_name); qlt_schedule_sess_for_deletion(fcport); continue; diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index a07bde90f..1c9ac2e37 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -1288,7 +1288,7 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess) qla24xx_chk_fcp_state(sess); - ql_dbg(ql_dbg_disc, sess->vha, 0xe001, + ql_dbg(ql_log_warn, sess->vha, 0xe001, "Scheduling sess %p for deletion %8phC\n", sess, sess->port_name); From bb519e83d17e312a7d6b4707d79a64e49f9ec805 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:38:04 +0000 Subject: [PATCH 46/56] qla2x00t-32gbit: Limit interrupt vectors to number of CPUs Driver created too many QPairs(126) with 28xx adapter. Limit to the number of CPUs to minimize wasted resources. Link: https://lore.kernel.org/r/20201202132312.19966-4-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit a6dcfe08487e5e83b6b4214c959a9577a9ed2d9f. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9292 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_isr.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index 636973bf7..abc0b4313 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -4056,10 +4056,12 @@ msix_failed: if (USER_CTRL_IRQ(ha) || !ha->mqiobase) { /* user wants to control IRQ setting for target mode */ ret = pci_alloc_irq_vectors(ha->pdev, min_vecs, - ha->msix_count, PCI_IRQ_MSIX); + min((u16)ha->msix_count, (u16)num_online_cpus()), + PCI_IRQ_MSIX); } else ret = pci_alloc_irq_vectors_affinity(ha->pdev, min_vecs, - ha->msix_count, PCI_IRQ_MSIX | PCI_IRQ_AFFINITY, + min((u16)ha->msix_count, (u16)num_online_cpus()), + PCI_IRQ_MSIX | PCI_IRQ_AFFINITY, &desc); #endif From 6464aae05b140ec74236a62ec49cbd0289b5d654 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:38:59 +0000 Subject: [PATCH 47/56] qla2x00t-32gbit: Tear down session if FW say it is down The completion status 0x28 (ppc = be = 0x2800) below indicates session is not there, trigger session deletion. qla2xxx [000b:04:00.1]-8009:8: DEVICE RESET ISSUED nexus=8:1:51 cmd=c000001432d0f600. qla2xxx [000b:04:00.1]-5039:8: Async-tmf error - hdl=67b completion status(2800). qla2xxx [000b:04:00.1]-8030:8: TM IOCB failed (102). qla2xxx [000b:04:00.1]-800c:8: do_reset failed for cmd=c000001432d0f600. qla2xxx [000b:04:00.1]-800f:8: DEVICE RESET FAILED: Task management failed nexus=8:1:51 cmd=c000001432d0f600. qla2xxx [000b:04:00.1]-8009:8: DEVICE RESET ISSUED nexus=8:1:52 cmd=c000001432d0c200. qla2xxx [000b:04:00.1]-5039:8: Async-tmf error - hdl=67c completion status(2800). qla2xxx [000b:04:00.1]-8030:8: TM IOCB failed (102). Link: https://lore.kernel.org/r/20201202132312.19966-5-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit e4fc78f48d3f8a9ea49e4b24878ac48dc9a58744. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9293 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_isr.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index abc0b4313..5ab559641 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -2246,11 +2246,13 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk) srb_t *sp; struct srb_iocb *iocb; struct sts_entry_24xx *sts = (struct sts_entry_24xx *)tsk; + u16 comp_status; sp = qla2x00_get_sp_from_handle(vha, func, req, tsk); if (!sp) return; + comp_status = le16_to_cpu(sts->comp_status); iocb = &sp->u.iocb_cmd; type = sp->name; fcport = sp->fcport; @@ -2264,7 +2266,7 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk) } else if (sts->comp_status != cpu_to_le16(CS_COMPLETE)) { ql_log(ql_log_warn, fcport->vha, 0x5039, "Async-%s error - hdl=%x completion status(%x).\n", - type, sp->handle, sts->comp_status); + type, sp->handle, comp_status); iocb->u.tmf.data = QLA_FUNCTION_FAILED; } else if ((le16_to_cpu(sts->scsi_status) & SS_RESPONSE_INFO_LEN_VALID)) { @@ -2280,6 +2282,30 @@ qla24xx_tm_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, void *tsk) } } + switch (comp_status) { + case CS_PORT_LOGGED_OUT: + case CS_PORT_CONFIG_CHG: + case CS_PORT_BUSY: + case CS_INCOMPLETE: + case CS_PORT_UNAVAILABLE: + case CS_TIMEOUT: + case CS_RESET: + if (atomic_read(&fcport->state) == FCS_ONLINE) { + ql_dbg(ql_dbg_disc, fcport->vha, 0x3021, + "-Port to be marked lost on fcport=%02x%02x%02x, current port state= %s comp_status %x.\n", + fcport->d_id.b.domain, fcport->d_id.b.area, + fcport->d_id.b.al_pa, + port_state_str[FCS_ONLINE], + comp_status); + + qlt_schedule_sess_for_deletion(fcport); + } + break; + + default: + break; + } + if (iocb->u.tmf.data != QLA_SUCCESS) ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, sp->vha, 0x5055, sts, sizeof(*sts)); From 260f713d87db1a4d7f54cd2d8fb6de7a0acacabf Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:39:33 +0000 Subject: [PATCH 48/56] qla2x00t-32gbit: Don't check for fw_started while posting NVMe command NVMe commands can come only after successful addition of rport and NVMe connect, and rport is only registered after FW started bit is set. Remove the redundant check. Link: https://lore.kernel.org/r/20201202132312.19966-6-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Saurav Kashyap Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit 0ce8ab50a6ed7c10bc3b7fc00d4aa5b67b5f9e2c. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9294 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_nvme.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/qla2x00t-32gbit/qla_nvme.c b/qla2x00t-32gbit/qla_nvme.c index aac984c76..f75385cc8 100644 --- a/qla2x00t-32gbit/qla_nvme.c +++ b/qla2x00t-32gbit/qla_nvme.c @@ -567,19 +567,15 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport, fcport = qla_rport->fcport; - if (!qpair || !fcport) - return -ENODEV; - - if (!qpair->fw_started || fcport->deleted) + if (unlikely(!qpair || !fcport || fcport->deleted)) return -EBUSY; - vha = fcport->vha; - if (!(fcport->nvme_flag & NVME_FLAG_REGISTERED)) return -ENODEV; - if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) || - (qpair && !qpair->fw_started) || fcport->deleted) + vha = fcport->vha; + + if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags)) return -EBUSY; /* From b885c5f4e5b526c312ce97d37370edb9ac49ca8d Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:41:05 +0000 Subject: [PATCH 49/56] qla2x00t-32gbit: Fix compilation issue in PPC systems Fix compile time errors reported on PPC systems, qla_gbl.h:991:20: error: inlining failed in call to always_inline qla_nvme_abort_set_option: function body not available Link: https://lore.kernel.org/r/20201202132312.19966-7-njavali@marvell.com Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit aceba54ba0f998ed6bec88faaf94e7458f753399. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9295 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_nx.c | 2 +- qla2x00t-32gbit/qla_nx2.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/qla2x00t-32gbit/qla_nx.c b/qla2x00t-32gbit/qla_nx.c index d38bc3f3a..cb02c5c78 100644 --- a/qla2x00t-32gbit/qla_nx.c +++ b/qla2x00t-32gbit/qla_nx.c @@ -969,7 +969,7 @@ qla82xx_read_status_reg(struct qla_hw_data *ha, uint32_t *val) static int qla82xx_flash_wait_write_finish(struct qla_hw_data *ha) { - uint32_t val; + uint32_t val = 0; int i, ret; scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); diff --git a/qla2x00t-32gbit/qla_nx2.c b/qla2x00t-32gbit/qla_nx2.c index 01ccd4526..68a16c95d 100644 --- a/qla2x00t-32gbit/qla_nx2.c +++ b/qla2x00t-32gbit/qla_nx2.c @@ -139,7 +139,7 @@ qla8044_poll_wait_for_ready(struct scsi_qla_host *vha, uint32_t addr1, uint32_t mask) { unsigned long timeout; - uint32_t temp; + uint32_t temp = 0; /* jiffies after 100ms */ timeout = jiffies + msecs_to_jiffies(TIMEOUT_100_MS); @@ -2594,7 +2594,7 @@ qla8044_minidump_process_rdmux(struct scsi_qla_host *vha, struct qla8044_minidump_entry_hdr *entry_hdr, uint32_t **d_ptr) { - uint32_t r_addr, s_stride, s_addr, s_value, loop_cnt, i, r_value; + uint32_t r_addr, s_stride, s_addr, s_value, loop_cnt, i, r_value = 0; struct qla8044_minidump_entry_mux *mux_hdr; uint32_t *data_ptr = *d_ptr; From baed87d219b7c80b42568f4e2ca3688f2a162ad2 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:46:16 +0000 Subject: [PATCH 50/56] qla2x00t-32gbit: Fix crash during driver load on big endian machines Crash stack: [576544.715489] Unable to handle kernel paging request for data at address 0xd00000000f970000 [576544.715497] Faulting instruction address: 0xd00000000f880f64 [576544.715503] Oops: Kernel access of bad area, sig: 11 [#1] [576544.715506] SMP NR_CPUS=2048 NUMA pSeries : [576544.715703] NIP [d00000000f880f64] .qla27xx_fwdt_template_valid+0x94/0x100 [qla2xxx] [576544.715722] LR [d00000000f7952dc] .qla24xx_load_risc_flash+0x2fc/0x590 [qla2xxx] [576544.715726] Call Trace: [576544.715731] [c0000004d0ffb000] [c0000006fe02c350] 0xc0000006fe02c350 (unreliable) [576544.715750] [c0000004d0ffb080] [d00000000f7952dc] .qla24xx_load_risc_flash+0x2fc/0x590 [qla2xxx] [576544.715770] [c0000004d0ffb170] [d00000000f7aa034] .qla81xx_load_risc+0x84/0x1a0 [qla2xxx] [576544.715789] [c0000004d0ffb210] [d00000000f79f7c8] .qla2x00_setup_chip+0xc8/0x910 [qla2xxx] [576544.715808] [c0000004d0ffb300] [d00000000f7a631c] .qla2x00_initialize_adapter+0x4dc/0xb00 [qla2xxx] [576544.715826] [c0000004d0ffb3e0] [d00000000f78ce28] .qla2x00_probe_one+0xf08/0x2200 [qla2xxx] Link: https://lore.kernel.org/r/20201202132312.19966-8-njavali@marvell.com Fixes: f73cb695d3ec ("[SCSI] qla2xxx: Add support for ISP2071.") Cc: stable@vger.kernel.org Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit 8de309e7299a00b3045fb274f82b326f356404f0. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9296 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_tmpl.c | 9 +++++---- qla2x00t-32gbit/qla_tmpl.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/qla2x00t-32gbit/qla_tmpl.c b/qla2x00t-32gbit/qla_tmpl.c index bd8623ee1..26c13a953 100644 --- a/qla2x00t-32gbit/qla_tmpl.c +++ b/qla2x00t-32gbit/qla_tmpl.c @@ -928,7 +928,8 @@ qla27xx_template_checksum(void *p, ulong size) static inline int qla27xx_verify_template_checksum(struct qla27xx_fwdt_template *tmp) { - return qla27xx_template_checksum(tmp, tmp->template_size) == 0; + return qla27xx_template_checksum(tmp, + le32_to_cpu(tmp->template_size)) == 0; } static inline int @@ -944,7 +945,7 @@ qla27xx_execute_fwdt_template(struct scsi_qla_host *vha, ulong len = 0; if (qla27xx_fwdt_template_valid(tmp)) { - len = tmp->template_size; + len = le32_to_cpu(tmp->template_size); tmp = memcpy(buf, tmp, len); ql27xx_edit_template(vha, tmp); qla27xx_walk_template(vha, tmp, buf, &len); @@ -960,7 +961,7 @@ qla27xx_fwdt_calculate_dump_size(struct scsi_qla_host *vha, void *p) ulong len = 0; if (qla27xx_fwdt_template_valid(tmp)) { - len = tmp->template_size; + len = le32_to_cpu(tmp->template_size); qla27xx_walk_template(vha, tmp, NULL, &len); } @@ -972,7 +973,7 @@ qla27xx_fwdt_template_size(void *p) { struct qla27xx_fwdt_template *tmp = p; - return tmp->template_size; + return le32_to_cpu(tmp->template_size); } int diff --git a/qla2x00t-32gbit/qla_tmpl.h b/qla2x00t-32gbit/qla_tmpl.h index c47184db5..6e0987edf 100644 --- a/qla2x00t-32gbit/qla_tmpl.h +++ b/qla2x00t-32gbit/qla_tmpl.h @@ -12,7 +12,7 @@ struct __packed qla27xx_fwdt_template { __le32 template_type; __le32 entry_offset; - uint32_t template_size; + __le32 template_size; uint32_t count; /* borrow field for running/residual count */ __le32 entry_count; From 68207cfbb04cc7ebe9c76d660afa9585ed093934 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:49:15 +0000 Subject: [PATCH 51/56] qla2x00t-32gbit: Handle aborts correctly for port undergoing deletion Call trace observed while shutting down the adapter ports (LINK DOWN). Handle aborts correctly. localhost kernel: INFO: task nvme:44209 blocked for more than 120 seconds. localhost kernel: "echo 0 >/proc/sys/kernel/hung_task_timeout_secs" disables this message. localhost kernel: nvme D ffff88b45fb5acc0 0 44209 1 0x00000080 localhost kernel: Call Trace: localhost kernel: [] schedule+0x29/0x70 localhost kernel: [] schedule_timeout+0x221/0x2d0 localhost kernel: [] ? ttwu_do_wakeup+0x19/0xe0 localhost kernel: [] ? ttwu_do_activate+0x6f/0x80 localhost kernel: [] ? try_to_wake_up+0x190/0x390 localhost kernel: [] wait_for_completion+0xfd/0x140 localhost kernel: [] ? wake_up_state+0x20/0x20 localhost kernel: [] flush_work+0x10a/0x1b0 localhost kernel: [] ? move_linked_works+0x90/0x90 localhost kernel: [] flush_delayed_work+0x3f/0x50 localhost kernel: [] nvme_fc_init_ctrl+0x657/0x6a0 [nvme_fc] localhost kernel: [] nvme_fc_create_ctrl+0x18a/0x210 [nvme_fc] localhost kernel: [] nvmf_dev_write+0x98f/0xb35 [nvme_fabrics] localhost kernel: [] ? security_file_permission+0x27/0xa0 localhost kernel: [] vfs_write+0xc0/0x1f0 localhost kernel: [] SyS_write+0x7f/0xf0 localhost kernel: [] system_call_fastpath+0x25/0x2a Link: https://lore.kernel.org/r/20201202132312.19966-11-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Saurav Kashyap Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit f795f96e725b472de59db06a21a23e2285faaf14. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9297 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 75 +++++++++++++++++++++++++++----------- qla2x00t-32gbit/qla_mbx.c | 9 ++--- qla2x00t-32gbit/qla_nvme.c | 2 +- 3 files changed, 58 insertions(+), 28 deletions(-) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 56b201b9f..7b550eb2b 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -1268,9 +1268,10 @@ qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport) lio->u.logio.flags |= SRB_LOGIN_NVME_PRLI; ql_dbg(ql_dbg_disc, vha, 0x211b, - "Async-prli - %8phC hdl=%x, loopid=%x portid=%06x retries=%d %s.\n", + "Async-prli - %8phC hdl=%x, loopid=%x portid=%06x retries=%d fc4type %x priority %x %s.\n", fcport->port_name, sp->handle, fcport->loop_id, fcport->d_id.b24, - fcport->login_retry, NVME_TARGET(vha->hw, fcport) ? "nvme" : "fc"); + fcport->login_retry, fcport->fc4_type, vha->hw->fc4_type_priority, + NVME_TARGET(vha->hw, fcport) ? "nvme" : "fcp"); rval = qla2x00_start_sp(sp); if (rval != QLA_SUCCESS) { @@ -1932,26 +1933,58 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea) break; } - /* - * Retry PRLI with other FC-4 type if failure occurred on dual - * FCP/NVMe port - */ - if (NVME_FCP_TARGET(ea->fcport)) { - ql_dbg(ql_dbg_disc, vha, 0x2118, - "%s %d %8phC post %s prli\n", - __func__, __LINE__, ea->fcport->port_name, - (ea->fcport->fc4_type & FS_FC4TYPE_NVME) ? - "NVMe" : "FCP"); - if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME) - ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME; - else - ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP; - } + ql_dbg(ql_dbg_disc, vha, 0x2118, + "%s %d %8phC priority %s, fc4type %x\n", + __func__, __LINE__, ea->fcport->port_name, + vha->hw->fc4_type_priority == FC4_PRIORITY_FCP ? + "FCP" : "NVMe", ea->fcport->fc4_type); - ea->fcport->flags &= ~FCF_ASYNC_SENT; - ea->fcport->keep_nport_handle = 0; - ea->fcport->logout_on_delete = 1; - qlt_schedule_sess_for_deletion(ea->fcport); + if (N2N_TOPO(vha->hw)) { + if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME) { + ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME; + ea->fcport->fc4_type |= FS_FC4TYPE_FCP; + } else { + ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP; + ea->fcport->fc4_type |= FS_FC4TYPE_NVME; + } + + if (ea->fcport->n2n_link_reset_cnt < 3) { + ea->fcport->n2n_link_reset_cnt++; + vha->relogin_jif = jiffies + 2 * HZ; + /* + * PRLI failed. Reset link to kick start + * state machine + */ + set_bit(N2N_LINK_RESET, &vha->dpc_flags); + } else { + ql_log(ql_log_warn, vha, 0x2119, + "%s %d %8phC Unable to reconnect\n", + __func__, __LINE__, + ea->fcport->port_name); + } + } else { + /* + * switch connect. login failed. Take connection down + * and allow relogin to retrigger + */ + if (NVME_FCP_TARGET(ea->fcport)) { + ql_dbg(ql_dbg_disc, vha, 0x2118, + "%s %d %8phC post %s prli\n", + __func__, __LINE__, + ea->fcport->port_name, + (ea->fcport->fc4_type & FS_FC4TYPE_NVME) + ? "NVMe" : "FCP"); + if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME) + ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME; + else + ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP; + } + + ea->fcport->flags &= ~FCF_ASYNC_SENT; + ea->fcport->keep_nport_handle = 0; + ea->fcport->logout_on_delete = 1; + qlt_schedule_sess_for_deletion(ea->fcport); + } break; } } diff --git a/qla2x00t-32gbit/qla_mbx.c b/qla2x00t-32gbit/qla_mbx.c index 40af7f152..d7d4ab650 100644 --- a/qla2x00t-32gbit/qla_mbx.c +++ b/qla2x00t-32gbit/qla_mbx.c @@ -1129,7 +1129,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha) if (ha->flags.scm_supported_a && (ha->fw_attributes_ext[0] & FW_ATTR_EXT0_SCM_SUPPORTED)) { ha->flags.scm_supported_f = 1; - ha->sf_init_cb->flags |= BIT_13; + ha->sf_init_cb->flags |= cpu_to_le16(BIT_13); } ql_log(ql_log_info, vha, 0x11a3, "SCM in FW: %s\n", (ha->flags.scm_supported_f) ? "Supported" : @@ -1137,9 +1137,9 @@ qla2x00_get_fw_version(scsi_qla_host_t *vha) if (vha->flags.nvme2_enabled) { /* set BIT_15 of special feature control block for SLER */ - ha->sf_init_cb->flags |= BIT_15; + ha->sf_init_cb->flags |= cpu_to_le16(BIT_15); /* set BIT_14 of special feature control block for PI CTRL*/ - ha->sf_init_cb->flags |= BIT_14; + ha->sf_init_cb->flags |= cpu_to_le16(BIT_14); } } @@ -3998,9 +3998,6 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, fcport->scan_state = QLA_FCPORT_FOUND; fcport->n2n_flag = 1; fcport->keep_nport_handle = 1; - fcport->fc4_type = FS_FC4TYPE_FCP; - if (vha->flags.nvme_enabled) - fcport->fc4_type |= FS_FC4TYPE_NVME; if (wwn_to_u64(vha->port_name) > wwn_to_u64(fcport->port_name)) { diff --git a/qla2x00t-32gbit/qla_nvme.c b/qla2x00t-32gbit/qla_nvme.c index f75385cc8..93d258a2c 100644 --- a/qla2x00t-32gbit/qla_nvme.c +++ b/qla2x00t-32gbit/qla_nvme.c @@ -240,7 +240,7 @@ static void qla_nvme_abort_work(struct work_struct *work) "%s called for sp=%p, hndl=%x on fcport=%p deleted=%d\n", __func__, sp, sp->handle, fcport, fcport->deleted); - if (!ha->flags.fw_started && fcport->deleted) + if (!ha->flags.fw_started || fcport->deleted) goto out; if (ha->flags.host_shutting_down) { From 44dd7f48a311d66e32d896ff05a62bf2aa5dc2cd Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:50:15 +0000 Subject: [PATCH 52/56] qla2x00t-32gbit: Fix flash update in 28XX adapters on big endian machines Flash update failed due to missing endian conversion in FLT region access as well as in checksum computation. Link: https://lore.kernel.org/r/20201202132312.19966-12-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit 0bc17251dff432f2589d3d509fb4dc14912d4372. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9298 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_sup.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/qla2x00t-32gbit/qla_sup.c b/qla2x00t-32gbit/qla_sup.c index 0f92e9a04..f771fabcb 100644 --- a/qla2x00t-32gbit/qla_sup.c +++ b/qla2x00t-32gbit/qla_sup.c @@ -2634,14 +2634,14 @@ qla28xx_extract_sfub_and_verify(struct scsi_qla_host *vha, uint32_t *buf, sizeof(struct secure_flash_update_block)); for (i = 0; i < (sizeof(struct secure_flash_update_block) >> 2); i++) - check_sum += p[i]; + check_sum += le32_to_cpu(p[i]); check_sum = (~check_sum) + 1; - if (check_sum != p[i]) { + if (check_sum != le32_to_cpu(p[i])) { ql_log(ql_log_warn, vha, 0x7097, "SFUB checksum failed, 0x%x, 0x%x\n", - check_sum, p[i]); + check_sum, le32_to_cpu(p[i])); return QLA_COMMAND_ERROR; } @@ -2721,7 +2721,7 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, if (ha->flags.secure_adapter && region.attribute) { ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff, - "Region %x is secure\n", region.code); + "Region %x is secure\n", le16_to_cpu(region.code)); switch (le16_to_cpu(region.code)) { case FLT_REG_FW: @@ -2775,7 +2775,7 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, default: ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff, "Secure region %x not supported\n", - region.code); + le16_to_cpu(region.code)); rval = QLA_COMMAND_ERROR; goto done; } From 3e72ee7690ebf9dbbeabcc552f5e6be6d50e0400 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:51:08 +0000 Subject: [PATCH 53/56] qla2x00t-32gbit: Fix the call trace for flush workqueue The call trace was because workqueue was allocated without any flags, added WQ_MEM_RECLAIM as flag when allocating. kernel: workqueue: WQ_MEM_RECLAIM kblockd:blk_mq_run_work_fn is flushing !WQ_MEM_RECLAIM qla2xxx_wq:0x0 kernel: WARNING: CPU: 0 PID: 2475 at kernel/workqueue.c:2593 check_flush_dependency+0x110/0x130 kernel: CPU: 0 PID: 2475 Comm: kworker/0:1H Kdump: loaded Tainted: G OE --------- - - 4.18.0-193.el8.x86_64 #1 kernel: Hardware name: HPE ProLiant XL170r Gen10/ProLiant XL170r Gen10, BIOS U38 05/21/2019 kernel: Workqueue: kblockd blk_mq_run_work_fn kernel: RIP: 0010:check_flush_dependency+0x110/0x130 kernel: Code: ff ff 48 8b 50 18 48 8d 8b b0 00 00 00 49 89 e8 48 81 c6 b0 00 00 00 48 c7 c7 00 1e e9 95 c6 05 dc 9a 2f 01 01 e8 1a 42 fe ff <0f> 0b e9 0a ff ff ff 80 3d ca 9a 2f 01 0 0 75 95 e9 41 ff ff ff 90 kernel: RSP: 0018:ffffa40f48b2baf8 EFLAGS: 00010282 kernel: RAX: 0000000000000000 RBX: ffff946795282600 RCX: 0000000000000000 kernel: RDX: 000000000000005f RSI: ffffffff96a1af7f RDI: 0000000000000246 kernel: RBP: 0000000000000000 R08: ffffffff96a1af20 R09: 0000000000029480 kernel: R10: 00080c89bb3e7462 R11: 00000000000009ab R12: ffff946773628000 kernel: R13: 0000000000000282 R14: 0000000000000246 R15: ffffa40f48b2bb40 kernel: FS: 0000000000000000(0000) GS:ffff94679fa00000(0000) knlGS:0000000000000000 kernel: CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 kernel: CR2: 00005570c4b60110 CR3: 000000029140a005 CR4: 00000000007606f0 kernel: DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 kernel: DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 kernel: PKRU: 55555554 kernel: Call Trace: kernel: flush_workqueue+0x13a/0x440 kernel: qla2x00_wait_for_sess_deletion+0x1d6/0x200 [qla2xxx] kernel: ? finish_wait+0x80/0x80 kernel: qla2xxx_disable_port+0x2b/0x30 [qla2xxx] kernel: qla2x00_process_vendor_specific+0x1dc9/0x2d20 [qla2xxx] kernel: ? blk_rq_map_sg+0x195/0x570 kernel: qla24xx_bsg_request+0x1a3/0xf90 [qla2xxx] Link: https://lore.kernel.org/r/20201202132312.19966-13-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Saurav Kashyap Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit 0a6f4d762c6b8fd0d442db74c8d279744100ae25. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9299 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 737d01eae..44869a479 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -3313,7 +3313,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) "req->req_q_in=%p req->req_q_out=%p rsp->rsp_q_in=%p rsp->rsp_q_out=%p.\n", req->req_q_in, req->req_q_out, rsp->rsp_q_in, rsp->rsp_q_out); - ha->wq = alloc_workqueue("qla2xxx_wq", 0, 0); + ha->wq = alloc_workqueue("qla2xxx_wq", WQ_MEM_RECLAIM, 0); if (unlikely(!ha->wq)) { ret = -ENOMEM; goto probe_failed; From ab98afb456cabef2b6153f152a4d7f9ec55454eb Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:51:49 +0000 Subject: [PATCH 54/56] qla2x00t-32gbit: If fcport is undergoing deletion complete I/O with retry Driver unload with I/Os in flight causes server to crash. Complete I/O with DID_IMM_RETRY if fcport undergoing deletion. CPU: 44 PID: 35008 Comm: qla2xxx_4_dpc Kdump: loaded Tainted: G OE X 5.3.18-22-default #1 SLE15-SP2 (unreleased) Hardware name: HPE ProLiant DL380 Gen10/ProLiant DL380 Gen10, BIOS U30 07/16/2020 RIP: 0010:dma_direct_unmap_sg+0x24/0x60 Code: 4c 8b 04 24 eb b9 0f 1f 44 00 00 85 d2 7e 4e 41 57 4d 89 c7 41 56 41 89 ce 41 55 49 89 fd 41 54 41 89 d4 55 31 ed 53 48 89 f3 <8b> 53 18 48 8b 73 10 4d 89 f8 44 89 f1 4c 89 ef 83 c5 01 e8 44 ff RSP: 0018:ffffc0c661037d88 EFLAGS: 00010046 RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000002 RDX: 000000000000001d RSI: 0000000000000000 RDI: ffff9a51ee53b0b0 RBP: 0000000000000000 R08: 0000000000000000 R09: ffff9a51ee53b0b0 R10: ffffc0c646463dc8 R11: ffff9a4a067087c8 R12: 000000000000001d R13: ffff9a51ee53b0b0 R14: 0000000000000002 R15: 0000000000000000 FS: 0000000000000000(0000) GS:ffff9a523f800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000018 CR3: 000000043740a004 CR4: 00000000007606e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: qla2xxx_qpair_sp_free_dma+0x20d/0x3c0 [qla2xxx] qla2xxx_qpair_sp_compl+0x35/0x90 [qla2xxx] __qla2x00_abort_all_cmds+0x180/0x390 [qla2xxx] ? qla24xx_process_purex_list+0x100/0x100 [qla2xxx] qla2x00_abort_all_cmds+0x5e/0x80 [qla2xxx] qla2x00_do_dpc+0x317/0xa30 [qla2xxx] kthread+0x10d/0x130 ? kthread_park+0xa0/0xa0 ret_from_fork+0x35/0x40 Link: https://lore.kernel.org/r/20201202132312.19966-14-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Saurav Kashyap Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit 707531bc2626c1959a03b93566ebb4e629c99276. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9300 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 44869a479..b7285a8e1 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -921,8 +921,8 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) goto qc24_fail_command; } - if (!fcport) { - cmd->result = DID_NO_CONNECT << 16; + if (!fcport || fcport->deleted) { + cmd->result = DID_IMM_RETRY << 16; goto qc24_fail_command; } @@ -1003,8 +1003,8 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd, goto qc24_fail_command; } - if (!fcport) { - cmd->result = DID_NO_CONNECT << 16; + if (!fcport || fcport->deleted) { + cmd->result = DID_IMM_RETRY << 16; goto qc24_fail_command; } From dad1b2cb9c1130e9c75c0693e4d78d795f600ab5 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:52:31 +0000 Subject: [PATCH 55/56] qla2x00t-32gbit: Fix device loss on 4G and older HBAs Due to a bug in the older scan logic, when a once lost device re-appeared, it was not discovered. Fix this by resetting login_retry counter upon device discovery. This is applicable only for 4G and older HBAs. Link: https://lore.kernel.org/r/20201202132312.19966-15-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit abd9cae9bbae9f3a80dae82587b1f79161ad7836. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9301 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 7b550eb2b..cf9eb58a9 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -5982,6 +5982,9 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) break; } + if (fcport->login_retry == 0) + fcport->login_retry = + vha->hw->login_retry_count; /* * If device was not a fabric device before. */ From 5055d80d368413cfb7cf49cf3794ba852d058de1 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Mon, 28 Dec 2020 23:53:31 +0000 Subject: [PATCH 56/56] qla2x00t-32gbit: Update version to 10.02.00.104-k Link: https://lore.kernel.org/r/20201202132312.19966-16-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen See also upstream commit afc516dcfe52802e0d29e37e3200c0f08583bd8f. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9302 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_version.h b/qla2x00t-32gbit/qla_version.h index c2d4da52f..ccec85887 100644 --- a/qla2x00t-32gbit/qla_version.h +++ b/qla2x00t-32gbit/qla_version.h @@ -6,9 +6,9 @@ /* * Driver version */ -#define QLA2XXX_VERSION "10.02.00.103-k" +#define QLA2XXX_VERSION "10.02.00.104-k" #define QLA_DRIVER_MAJOR_VER 10 #define QLA_DRIVER_MINOR_VER 2 #define QLA_DRIVER_PATCH_VER 0 -#define QLA_DRIVER_BETA_VER 103 +#define QLA_DRIVER_BETA_VER 104