From 0640b6ba495754833d77d0709d69f7189112bd51 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 20:33:29 +0000 Subject: [PATCH 01/29] qla2x00t-32gbit: Replace __qla2x00_marker()'s missing underscores Fixes the following W=1 kernel build warning(s): drivers/scsi/qla2xxx/qla_iocb.c:508: warning: expecting prototype for qla2x00_marker(). Prototype was for __qla2x00_marker() instead Link: https://lore.kernel.org/r/20210303144631.3175331-16-lee.jones@linaro.org Cc: Nilesh Javali Cc: GR-QLogic-Storage-Upstream@marvell.com Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Acked-by: Nilesh Javali Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen [ commit 52bb80f18def787e98a9f97a7cabbe71e4879996 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9389 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_iocb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index 14ada875f..4bd6bc004 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -491,7 +491,7 @@ qla2x00_start_iocbs(struct scsi_qla_host *vha, struct req_que *req) } /** - * qla2x00_marker() - Send a marker IOCB to the firmware. + * __qla2x00_marker() - Send a marker IOCB to the firmware. * @vha: HA context * @qpair: queue pair pointer * @loop_id: loop ID From df9671d11c2cb9c07e3dc1e03b3baf18362f98b4 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 20:34:10 +0000 Subject: [PATCH 02/29] Update the Subversion global-ignores property git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9390 d57e44dd-8a1f-0410-8b47-8ef2f437770f From 853ea68d851c2397708b03183f972b8e4eda6455 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 20:35:09 +0000 Subject: [PATCH 03/29] qla2x00t-32gbit: Fix some incorrect formatting/spelling issues Fixes the following W=1 kernel build warning(s): drivers/scsi/qla2xxx/qla_gs.c:1259: warning: expecting prototype for qla2x00_snd_rft_id(). Prototype was for qla2x00_sns_rft_id() instead drivers/scsi/qla2xxx/qla_gs.c:1492: warning: expecting prototype for qla2x00_prep_ct_req(). Prototype was for qla2x00_prep_ct_fdmi_req() instead drivers/scsi/qla2xxx/qla_gs.c:1596: warning: expecting prototype for perform HBA attributes registration(). Prototype was for qla2x00_hba_attributes() instead drivers/scsi/qla2xxx/qla_gs.c:1851: warning: expecting prototype for perform Port attributes registration(). Prototype was for qla2x00_port_attributes() instead drivers/scsi/qla2xxx/qla_gs.c:2284: warning: expecting prototype for perform RPRT registration(). Prototype was for qla2x00_fdmi_rprt() instead Link: https://lore.kernel.org/r/20210303144631.3175331-24-lee.jones@linaro.org Cc: Nilesh Javali Cc: GR-QLogic-Storage-Upstream@marvell.com Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" [ commit f11c8b42423f3b32c30bd985333e7378226b832d upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9391 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_gs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/qla2x00t-32gbit/qla_gs.c b/qla2x00t-32gbit/qla_gs.c index 517d358b0..8e126afe6 100644 --- a/qla2x00t-32gbit/qla_gs.c +++ b/qla2x00t-32gbit/qla_gs.c @@ -1247,7 +1247,7 @@ qla2x00_sns_gnn_id(scsi_qla_host_t *vha, sw_info_t *list) } /** - * qla2x00_snd_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA. + * qla2x00_sns_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA. * @vha: HA context * * This command uses the old Exectute SNS Command mailbox routine. @@ -1479,7 +1479,7 @@ qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size) } /** - * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query. + * qla2x00_prep_ct_fdmi_req() - Prepare common CT request fields for SNS query. * @p: CT request buffer * @cmd: GS command * @rsp_size: response size in bytes @@ -1582,7 +1582,7 @@ qla25xx_fdmi_port_speed_currently(struct qla_hw_data *ha) } /** - * qla2x00_hba_attributes() perform HBA attributes registration + * qla2x00_hba_attributes() - perform HBA attributes registration * @vha: HA context * @entries: number of entries to use * @callopt: Option to issue extended or standard FDMI @@ -1837,7 +1837,7 @@ done: } /** - * qla2x00_port_attributes() perform Port attributes registration + * qla2x00_port_attributes() - perform Port attributes registration * @vha: HA context * @entries: number of entries to use * @callopt: Option to issue extended or standard FDMI @@ -2272,7 +2272,7 @@ qla2x00_fdmi_dhba(scsi_qla_host_t *vha) } /** - * qla2x00_fdmi_rprt() perform RPRT registration + * qla2x00_fdmi_rprt() - perform RPRT registration * @vha: HA context * @callopt: Option to issue extended or standard FDMI * command parameter From 696b85fe84c5ae48c66a9dad1792940fdca0999f Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 20:36:27 +0000 Subject: [PATCH 04/29] qla2x00t-32gbit: Fix a couple of misnamed functions Fixes the following W=1 kernel build warning(s): drivers/scsi/qla2xxx/qla_mr.c:525: warning: expecting prototype for qlafx00_warm_reset(). Prototype was for qlafx00_soc_cpu_reset() instead drivers/scsi/qla2xxx/qla_mr.c:2869: warning: expecting prototype for qlafx00x_mbx_completion(). Prototype was for qlafx00_mbx_completion() instead Link: https://lore.kernel.org/r/20210312094738.2207817-9-lee.jones@linaro.org Cc: Nilesh Javali Cc: GR-QLogic-Storage-Upstream@marvell.com Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen [ commit 381095668d51387657e456e2962f0bcc3e1044e3 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9392 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_mr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_mr.c b/qla2x00t-32gbit/qla_mr.c index 608e06777..16d00e3e3 100644 --- a/qla2x00t-32gbit/qla_mr.c +++ b/qla2x00t-32gbit/qla_mr.c @@ -516,7 +516,7 @@ qlafx00_pci_config(scsi_qla_host_t *vha) } /** - * qlafx00_warm_reset() - Perform warm reset of iSA(CPUs being reset on SOC). + * qlafx00_soc_cpu_reset() - Perform warm reset of iSA(CPUs being reset on SOC). * @vha: HA context * */ @@ -2875,7 +2875,7 @@ qlafx00_async_event(scsi_qla_host_t *vha) } /** - * qlafx00x_mbx_completion() - Process mailbox command completions. + * qlafx00_mbx_completion() - Process mailbox command completions. * @vha: SCSI driver HA context * @mb0: value to be written into mailbox register 0 */ From 7768af7b3f7f8db8bef7c07c3f2e2603615b5099 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:14:07 +0000 Subject: [PATCH 05/29] qla2x00t-32gbit: Fix incorrectly named function qla8044_check_temp() Fixes the following W=1 kernel build warning(s): drivers/scsi/qla2xxx/qla_nx2.c:2038: warning: expecting prototype for qla4_8xxx_check_temp(). Prototype was for qla8044_check_temp() instead Link: https://lore.kernel.org/r/20210312094738.2207817-11-lee.jones@linaro.org Cc: Nilesh Javali Cc: GR-QLogic-Storage-Upstream@marvell.com Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen [ commit a736e44904422ade7af4ac50c64f58617ae4b7ba upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9393 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 68a16c95d..7c413f93d 100644 --- a/qla2x00t-32gbit/qla_nx2.c +++ b/qla2x00t-32gbit/qla_nx2.c @@ -2028,7 +2028,7 @@ exit_error: } /** - * qla4_8xxx_check_temp - Check the ISP82XX temperature. + * qla8044_check_temp - Check the ISP82XX temperature. * @vha: adapter block pointer. * * Note: The caller should not hold the idc lock. From 966e499270b80f8e8d0cab615b78583f9a1de5d7 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:15:35 +0000 Subject: [PATCH 06/29] qla2x00t-32gbit: Fix a couple of misdocumented functions Fixes the following W=1 kernel build warning(s): drivers/scsi/qla2xxx/qla_target.c:6476: warning: expecting prototype for qla_tgt_lport_register(). Prototype was for qlt_lport_register() instead drivers/scsi/qla2xxx/qla_target.c:6546: warning: expecting prototype for qla_tgt_lport_deregister(). Prototype was for qlt_lport_deregister() instead Link: https://lore.kernel.org/r/20210312094738.2207817-12-lee.jones@linaro.org Cc: Nilesh Javali Cc: GR-QLogic-Storage-Upstream@marvell.com Cc: "James E.J. Bottomley" Cc: "Martin K. Petersen" Cc: Vladislav Bolkhovitin Cc: Nathaniel Clark Cc: "Nicholas A. Bellinger" Cc: linux-scsi@vger.kernel.org Signed-off-by: Lee Jones Signed-off-by: Martin K. Petersen [ commit dc49ab48a77c48b3334ec57c2163f92721b06b5e upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9394 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_target.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index 8ba4e207c..868662611 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -6527,7 +6527,7 @@ static void qlt_lport_dump(struct scsi_qla_host *vha, u64 wwpn, } /** - * qla_tgt_lport_register - register lport with external module + * qlt_lport_register - register lport with external module * * @target_lport_ptr: pointer for tcm_qla2xxx specific lport data * @phys_wwpn: physical port WWPN @@ -6603,7 +6603,7 @@ int qlt_lport_register(void *target_lport_ptr, u64 phys_wwpn, EXPORT_SYMBOL(qlt_lport_register); /** - * qla_tgt_lport_deregister - Degister lport + * qlt_lport_deregister - Degister lport * * @vha: Registered scsi_qla_host pointer */ From adeb0e3b010006581df8ddf2192d57feceaf253d Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:19:37 +0000 Subject: [PATCH 07/29] qla2x00t-32gbit: Use dma_pool_zalloc() Use dma_pool_zalloc() instead of dma_pool_alloc() and memset(). Link: https://lore.kernel.org/r/1615603275-14303-1-git-send-email-wangqing@vivo.com Reviewed-by: Himanshu Madhani Signed-off-by: Wang Qing Signed-off-by: Martin K. Petersen [ commit 720efdd23f963612d0a8c7072293aff119c6f915 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9395 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index ba6b00b01..2d72264bc 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -4286,11 +4286,10 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len, /* Get consistent memory allocated for Special Features-CB. */ if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { - ha->sf_init_cb = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, + ha->sf_init_cb = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &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 b23a4fffc641801015aa1264031f8714bdcb31fa Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:21:02 +0000 Subject: [PATCH 08/29] qla2x00t-32gbit: Fix broken #endif placement Only half of the file is under include guard because terminating #endif is placed too early. Link: https://lore.kernel.org/r/YE4snvoW1SuwcXAn@localhost.localdomain Reviewed-by: Himanshu Madhani Signed-off-by: Alexey Dobriyan Signed-off-by: Martin K. Petersen [ commit 5999b9e5b1f8a2f5417b755130919b3ac96f5550 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9396 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_target.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_target.h b/qla2x00t-32gbit/qla_target.h index 8afdc4b64..aaf8b6216 100644 --- a/qla2x00t-32gbit/qla_target.h +++ b/qla2x00t-32gbit/qla_target.h @@ -143,7 +143,6 @@ (min(1270, ((ql) > 0) ? (QLA_TGT_DATASEGS_PER_CMD_24XX + \ QLA_TGT_DATASEGS_PER_CONT_24XX*((ql) - 1)) : 0)) #endif -#endif #define GET_TARGET_ID(ha, iocb) ((HAS_EXTENDED_IDS(ha)) \ ? le16_to_cpu((iocb)->u.isp2x.target.extended) \ @@ -271,6 +270,7 @@ struct ctio_to_2xxx { #ifndef CTIO_RET_TYPE #define CTIO_RET_TYPE 0x17 /* CTIO return entry */ #define ATIO_TYPE7 0x06 /* Accept target I/O entry for 24xx */ +#endif struct fcp_hdr { uint8_t r_ctl; From fb4f59a7c60bffcdb3b37c5911c65d49da50da8b Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:23:27 +0000 Subject: [PATCH 09/29] qla2x00t-32gbit: Constify struct qla_tgt_func_tmpl Since the target function pointers are not modified at runtime, declare the data structure with the target function pointers const. Link: https://lore.kernel.org/r/20210320232359.941-3-bvanassche@acm.org Cc: Quinn Tran Cc: Mike Christie Reviewed-by: Daniel Wagner Reviewed-by: Himanshu Madhani Reviewed-by: Lee Duncan Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen [ commit 634b9774d335020e2cd55950a6c1242e7e3bd1e7 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9397 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index 7df2eee7b..be0550011 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -3842,7 +3842,7 @@ struct qlt_hw_data { __le32 __iomem *atio_q_in; __le32 __iomem *atio_q_out; - struct qla_tgt_func_tmpl *tgt_ops; + const struct qla_tgt_func_tmpl *tgt_ops; struct qla_tgt_vp_map *tgt_vp_map; int saved_set; From aef48f05017fa0229c08ae6e968117077e4808b7 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:24:34 +0000 Subject: [PATCH 10/29] qla2x00t-32gbit: Fix endianness annotations Fix all recently introduced endianness annotation issues. Link: https://lore.kernel.org/r/20210320232359.941-4-bvanassche@acm.org Cc: Quinn Tran Cc: Mike Christie Reviewed-by: Daniel Wagner Reviewed-by: Himanshu Madhani Reviewed-by: Lee Duncan Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen [ commit 37ce4f3531d4a38f3f598fab45d80be5b46aee3c upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9398 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 2 +- qla2x00t-32gbit/qla_iocb.c | 3 ++- qla2x00t-32gbit/qla_isr.c | 2 +- qla2x00t-32gbit/qla_sup.c | 9 +++++---- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index be0550011..f7a5c9d40 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -1553,7 +1553,7 @@ struct init_sf_cb { * BIT_12 = Remote Write Optimization (1 - Enabled, 0 - Disabled) * BIT 11-0 = Reserved */ - uint16_t flags; + __le16 flags; uint8_t reserved1[32]; uint16_t discard_OHRB_timeout_value; uint16_t remote_write_opt_queue_num; diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index 4bd6bc004..732ddbd07 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -2385,7 +2385,8 @@ qla24xx_prli_iocb(srb_t *sp, struct logio_entry_24xx *logio) cpu_to_le32(NVME_PRLI_SP_FIRST_BURST); if (sp->vha->flags.nvme2_enabled) { /* Set service parameter BIT_7 for NVME CONF support */ - logio->io_parameter[0] |= NVME_PRLI_SP_CONF; + logio->io_parameter[0] |= + cpu_to_le32(NVME_PRLI_SP_CONF); /* Set service parameter BIT_8 for SLER support */ logio->io_parameter[0] |= cpu_to_le32(NVME_PRLI_SP_SLER); diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index 4f9d19d8b..1edb2276d 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -3475,7 +3475,7 @@ qla24xx_abort_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, return; abt = &sp->u.iocb_cmd; - abt->u.abt.comp_status = le16_to_cpu(pkt->comp_status); + abt->u.abt.comp_status = pkt->comp_status; orig_sp = sp->cmd_sp; /* Need to pass original sp */ if (orig_sp) diff --git a/qla2x00t-32gbit/qla_sup.c b/qla2x00t-32gbit/qla_sup.c index f771fabcb..060c89237 100644 --- a/qla2x00t-32gbit/qla_sup.c +++ b/qla2x00t-32gbit/qla_sup.c @@ -2621,10 +2621,11 @@ qla24xx_read_optrom_data(struct scsi_qla_host *vha, void *buf, } static int -qla28xx_extract_sfub_and_verify(struct scsi_qla_host *vha, uint32_t *buf, +qla28xx_extract_sfub_and_verify(struct scsi_qla_host *vha, __le32 *buf, uint32_t len, uint32_t buf_size_without_sfub, uint8_t *sfub_buf) { - uint32_t *p, check_sum = 0; + uint32_t check_sum = 0; + __le32 *p; int i; p = buf + buf_size_without_sfub; @@ -2790,8 +2791,8 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, goto done; } - rval = qla28xx_extract_sfub_and_verify(vha, dwptr, dwords, - buf_size_without_sfub, (uint8_t *)sfub); + rval = qla28xx_extract_sfub_and_verify(vha, (__le32 *)dwptr, + dwords, buf_size_without_sfub, (uint8_t *)sfub); if (rval != QLA_SUCCESS) goto done; From 0b7340af600911b9a1af31c7be4dc35a9a97a7e2 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:26:10 +0000 Subject: [PATCH 11/29] qla2x00t-32gbit: Simplify qla8044_minidump_process_control() This patch fixes the following Coverity complaint: CID 177490 (#1 of 1): Unused value (UNUSED_VALUE) assigned_value: Assigning value from opcode & 0xffffff7fU to opcode here, but that stored value is overwritten before it can be used. Link: https://lore.kernel.org/r/20210320232359.941-6-bvanassche@acm.org Cc: Quinn Tran Cc: Mike Christie Reviewed-by: Daniel Wagner Reviewed-by: Himanshu Madhani Reviewed-by: Lee Duncan Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen [ commit a20821e3f4719458a888af634c10c286365ecd6f upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9399 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_nx2.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/qla2x00t-32gbit/qla_nx2.c b/qla2x00t-32gbit/qla_nx2.c index 7c413f93d..5ceecc964 100644 --- a/qla2x00t-32gbit/qla_nx2.c +++ b/qla2x00t-32gbit/qla_nx2.c @@ -2226,19 +2226,16 @@ qla8044_minidump_process_control(struct scsi_qla_host *vha, if (opcode & QLA82XX_DBG_OPCODE_WR) { qla8044_wr_reg_indirect(vha, crb_addr, crb_entry->value_1); - opcode &= ~QLA82XX_DBG_OPCODE_WR; } if (opcode & QLA82XX_DBG_OPCODE_RW) { qla8044_rd_reg_indirect(vha, crb_addr, &read_value); qla8044_wr_reg_indirect(vha, crb_addr, read_value); - opcode &= ~QLA82XX_DBG_OPCODE_RW; } if (opcode & QLA82XX_DBG_OPCODE_AND) { qla8044_rd_reg_indirect(vha, crb_addr, &read_value); read_value &= crb_entry->value_2; - opcode &= ~QLA82XX_DBG_OPCODE_AND; if (opcode & QLA82XX_DBG_OPCODE_OR) { read_value |= crb_entry->value_3; opcode &= ~QLA82XX_DBG_OPCODE_OR; @@ -2249,7 +2246,6 @@ qla8044_minidump_process_control(struct scsi_qla_host *vha, qla8044_rd_reg_indirect(vha, crb_addr, &read_value); read_value |= crb_entry->value_3; qla8044_wr_reg_indirect(vha, crb_addr, read_value); - opcode &= ~QLA82XX_DBG_OPCODE_OR; } if (opcode & QLA82XX_DBG_OPCODE_POLL) { poll_time = crb_entry->crb_strd.poll_timeout; @@ -2269,7 +2265,6 @@ qla8044_minidump_process_control(struct scsi_qla_host *vha, crb_addr, &read_value); } } while (1); - opcode &= ~QLA82XX_DBG_OPCODE_POLL; } if (opcode & QLA82XX_DBG_OPCODE_RDSTATE) { @@ -2283,7 +2278,6 @@ qla8044_minidump_process_control(struct scsi_qla_host *vha, qla8044_rd_reg_indirect(vha, addr, &read_value); index = crb_entry->crb_ctrl.state_index_v; tmplt_hdr->saved_state_array[index] = read_value; - opcode &= ~QLA82XX_DBG_OPCODE_RDSTATE; } if (opcode & QLA82XX_DBG_OPCODE_WRSTATE) { @@ -2303,7 +2297,6 @@ qla8044_minidump_process_control(struct scsi_qla_host *vha, } qla8044_wr_reg_indirect(vha, addr, read_value); - opcode &= ~QLA82XX_DBG_OPCODE_WRSTATE; } if (opcode & QLA82XX_DBG_OPCODE_MDSTATE) { @@ -2316,7 +2309,6 @@ qla8044_minidump_process_control(struct scsi_qla_host *vha, read_value |= crb_entry->value_3; read_value += crb_entry->value_1; tmplt_hdr->saved_state_array[index] = read_value; - opcode &= ~QLA82XX_DBG_OPCODE_MDSTATE; } crb_addr += crb_entry->crb_strd.addr_stride; } From a5b92ce2452c3030d9781e0d7c309e374cef16d1 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:27:13 +0000 Subject: [PATCH 12/29] qla2x00t-32gbit: Check kzalloc() return value Instead of crashing if kzalloc() fails, make qla2x00_get_host_stats() return -ENOMEM. Link: https://lore.kernel.org/r/20210320232359.941-8-bvanassche@acm.org Fixes: dbf1f53cfd23 ("scsi: qla2xxx: Implementation to get and manage host, target stats and initiator port") Cc: Himanshu Madhani Cc: Saurav Kashyap Cc: Nilesh Javali Cc: Quinn Tran Cc: Mike Christie Cc: Daniel Wagner Cc: Lee Duncan Reviewed-by: Daniel Wagner Reviewed-by: Himanshu Madhani Acked-by: Saurav Kashyap Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen [ commit e5406d8ad4a1659f4d4d1b39fe203855c4eaef2d upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9400 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_bsg.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/qla2x00t-32gbit/qla_bsg.c b/qla2x00t-32gbit/qla_bsg.c index b37851583..8989c7ad5 100644 --- a/qla2x00t-32gbit/qla_bsg.c +++ b/qla2x00t-32gbit/qla_bsg.c @@ -2725,6 +2725,10 @@ qla2x00_get_host_stats(struct bsg_job *bsg_job) } data = kzalloc(response_len, GFP_KERNEL); + if (!data) { + kfree(req_data); + return -ENOMEM; + } ret = qla2xxx_get_ini_stats(fc_bsg_to_shost(bsg_job), req_data->stat_type, data, response_len); From 69743a4fda76dd04d5d5e4faffbf2bda2866e7cf Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:28:25 +0000 Subject: [PATCH 13/29] qla2x00t-32gbit: Fix IOPS drop seen in some adapters Removing the response queue processing in the send path is showing IOPS drop. Add back the process_response_queue() call in the send path. Link: https://lore.kernel.org/r/20210329085229.4367-2-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen [ commit bcafad6c2d520df42c86f28357d639deac15bad7 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9401 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_iocb.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index 732ddbd07..6291aca12 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -1606,12 +1606,14 @@ qla24xx_start_scsi(srb_t *sp) uint16_t req_cnt; uint16_t tot_dsds; struct req_que *req = NULL; + struct rsp_que *rsp; struct scsi_cmnd *cmd = GET_CMD_SP(sp); struct scsi_qla_host *vha = sp->vha; struct qla_hw_data *ha = vha->hw; /* Setup device pointers. */ req = vha->req; + rsp = req->rsp; /* So we know we haven't pci_map'ed anything yet */ tot_dsds = 0; @@ -1713,6 +1715,11 @@ qla24xx_start_scsi(srb_t *sp) /* Set chip new ring index. */ wrt_reg_dword(req->req_q_in, req->ring_index); + /* Manage unprocessed RIO/ZIO commands in response queue. */ + if (vha->flags.process_response_queue && + rsp->ring_ptr->signature != RESPONSE_PROCESSED) + qla24xx_process_response_queue(vha, rsp); + spin_unlock_irqrestore(&ha->hardware_lock, flags); return QLA_SUCCESS; @@ -1903,6 +1910,11 @@ qla24xx_dif_start_scsi(srb_t *sp) /* Set chip new ring index. */ wrt_reg_dword(req->req_q_in, req->ring_index); + /* Manage unprocessed RIO/ZIO commands in response queue. */ + if (vha->flags.process_response_queue && + rsp->ring_ptr->signature != RESPONSE_PROCESSED) + qla24xx_process_response_queue(vha, rsp); + spin_unlock_irqrestore(&ha->hardware_lock, flags); return QLA_SUCCESS; @@ -1937,6 +1949,7 @@ qla2xxx_start_scsi_mq(srb_t *sp) uint16_t req_cnt; uint16_t tot_dsds; struct req_que *req = NULL; + struct rsp_que *rsp; struct scsi_cmnd *cmd = GET_CMD_SP(sp); struct scsi_qla_host *vha = sp->fcport->vha; struct qla_hw_data *ha = vha->hw; @@ -1947,6 +1960,7 @@ qla2xxx_start_scsi_mq(srb_t *sp) /* Setup qpair pointers */ req = qpair->req; + rsp = qpair->rsp; /* So we know we haven't pci_map'ed anything yet */ tot_dsds = 0; @@ -2047,6 +2061,11 @@ qla2xxx_start_scsi_mq(srb_t *sp) /* Set chip new ring index. */ wrt_reg_dword(req->req_q_in, req->ring_index); + /* Manage unprocessed RIO/ZIO commands in response queue. */ + if (vha->flags.process_response_queue && + rsp->ring_ptr->signature != RESPONSE_PROCESSED) + qla24xx_process_response_queue(vha, rsp); + spin_unlock_irqrestore(&qpair->qp_lock, flags); return QLA_SUCCESS; From 19aa46c0dbab6da9d8bb7a5f0091c43b568b0e3a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:29:11 +0000 Subject: [PATCH 14/29] qla2x00t-32gbit: Add H:C:T info in the log message for fc ports The host:channel:scsi_target_id information is helpful in matching an FC port with a SCSI device, so add it. For initiator FC ports, a -1 would be displayed for "target" part. Link: https://lore.kernel.org/r/20210329085229.4367-3-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen [ commit a63f4c45414951ad4fbaeb5b744e37ffd137b689 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9402 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 068579863..e8ceff270 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -5512,13 +5512,14 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport) if (fcport->port_type & FCT_NVME_DISCOVERY) rport_ids.roles |= FC_PORT_ROLE_NVME_DISCOVERY; + fc_remote_port_rolechg(rport, rport_ids.roles); + ql_dbg(ql_dbg_disc, vha, 0x20ee, - "%s %8phN. rport %p is %s mode\n", - __func__, fcport->port_name, rport, + "%s: %8phN. rport %ld:0:%d (%p) is %s mode\n", + __func__, fcport->port_name, vha->host_no, + rport->scsi_target_id, rport, (fcport->port_type == FCT_TARGET) ? "tgt" : ((fcport->port_type & FCT_NVME) ? "nvme" : "ini")); - - fc_remote_port_rolechg(rport, rport_ids.roles); } /* From 9ef04479106df2aafab87d19aa4e3466bca5c8c5 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:29:59 +0000 Subject: [PATCH 15/29] qla2x00t-32gbit: Fix stuck session Session was stuck due to explicit logout to target timing out. The target was in an unresponsive state. This timeout induced an error to the GNL command from moving forward. Link: https://lore.kernel.org/r/20210329085229.4367-4-njavali@marvell.com Tested-by: Laurence Oberman Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen [ commit c358a3d92b32be89ea1c44fe75721448c0a0fec1 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9403 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 1 + qla2x00t-32gbit/qla_target.c | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index e8ceff270..6eb22fd50 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -718,6 +718,7 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha, ql_dbg(ql_dbg_disc, vha, 0x20e0, "%s %8phC login gen changed\n", __func__, fcport->port_name); + set_bit(RELOGIN_NEEDED, &vha->dpc_flags); return; } diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index 868662611..659bdbb6e 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -1044,7 +1044,12 @@ void qlt_free_session_done(struct work_struct *work) } msleep(100); cnt++; - if (cnt > 200) + /* + * Driver timeout is set to 22 Sec, update count value to loop + * long enough for log-out to complete before advancing. Otherwise, + * straddling logout can interfere with re-login attempt. + */ + if (cnt > 230) break; } From 186b41114c6035c90b0a82b9f1ca2b3cf2277d4e Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:30:53 +0000 Subject: [PATCH 16/29] qla2x00t-32gbit: Consolidate zio threshold setting for both FCP & NVMe Consolidate zio threshold setting for both FCP & NVMe to prevent one protocol from clobbering the setting of the other protocol. Link: https://lore.kernel.org/r/20210329085229.4367-5-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen [ commit 5777fef788a59f5ac9ab6661988a95a045fc0574 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9404 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 1 - qla2x00t-32gbit/qla_os.c | 36 +++++++++++++++--------------------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index f7a5c9d40..ac0b5f3b3 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -4754,7 +4754,6 @@ typedef struct scsi_qla_host { #define FX00_CRITEMP_RECOVERY 25 #define FX00_HOST_INFO_RESEND 26 #define QPAIR_ONLINE_CHECK_NEEDED 27 -#define SET_NVME_ZIO_THRESHOLD_NEEDED 28 #define DETECT_SFP_CHANGE 29 #define N2N_LOGIN_NEEDED 30 #define IOCB_WORK_ACTIVE 31 diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 2d72264bc..1461cffe9 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -7020,26 +7020,21 @@ intr_on_check: mutex_unlock(&ha->mq_lock); } - if (test_and_clear_bit(SET_NVME_ZIO_THRESHOLD_NEEDED, - &base_vha->dpc_flags)) { - ql_log(ql_log_info, base_vha, 0xffffff, - "nvme: SET ZIO Activity exchange threshold to %d.\n", - ha->nvme_last_rptd_aen); - if (qla27xx_set_zio_threshold(base_vha, - ha->nvme_last_rptd_aen)) { - ql_log(ql_log_info, base_vha, 0xffffff, - "nvme: Unable to SET ZIO Activity exchange threshold to %d.\n", - ha->nvme_last_rptd_aen); - } - } - if (test_and_clear_bit(SET_ZIO_THRESHOLD_NEEDED, - &base_vha->dpc_flags)) { + &base_vha->dpc_flags)) { + u16 threshold = ha->nvme_last_rptd_aen + ha->last_zio_threshold; + + if (threshold > ha->orig_fw_xcb_count) + threshold = ha->orig_fw_xcb_count; + ql_log(ql_log_info, base_vha, 0xffffff, - "SET ZIO Activity exchange threshold to %d.\n", - ha->last_zio_threshold); - qla27xx_set_zio_threshold(base_vha, - ha->last_zio_threshold); + "SET ZIO Activity exchange threshold to %d.\n", + threshold); + if (qla27xx_set_zio_threshold(base_vha, threshold)) { + ql_log(ql_log_info, base_vha, 0xffffff, + "Unable to SET ZIO Activity exchange threshold to %d.\n", + threshold); + } } if (!IS_QLAFX00(ha)) @@ -7269,14 +7264,13 @@ qla2x00_timer(struct timer_list *t) index = atomic_read(&ha->nvme_active_aen_cnt); if (!vha->vp_idx && (index != ha->nvme_last_rptd_aen) && - (index >= DEFAULT_ZIO_THRESHOLD) && ha->zio_mode == QLA_ZIO_MODE_6 && !ha->flags.host_shutting_down) { + ha->nvme_last_rptd_aen = atomic_read(&ha->nvme_active_aen_cnt); ql_log(ql_log_info, vha, 0x3002, "nvme: Sched: Set ZIO exchange threshold to %d.\n", ha->nvme_last_rptd_aen); - ha->nvme_last_rptd_aen = atomic_read(&ha->nvme_active_aen_cnt); - set_bit(SET_NVME_ZIO_THRESHOLD_NEEDED, &vha->dpc_flags); + set_bit(SET_ZIO_THRESHOLD_NEEDED, &vha->dpc_flags); start_dpc++; } From 01d7128916918137030c3cc916c8daab6f12c556 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:32:07 +0000 Subject: [PATCH 17/29] qla2x00t-32gbit: Fix use after free in bsg On bsg command completion, bsg_job_done() was called while qla driver continued to access the bsg_job buffer. bsg_job_done() would free up resources that ended up being reused by other task while the driver continued to access the buffers. As a result, driver was reading garbage data. localhost kernel: BUG: KASAN: use-after-free in sg_next+0x64/0x80 localhost kernel: Read of size 8 at addr ffff8883228a3330 by task swapper/26/0 localhost kernel: localhost kernel: CPU: 26 PID: 0 Comm: swapper/26 Kdump: loaded Tainted: G OE --------- - - 4.18.0-193.el8.x86_64+debug #1 localhost kernel: Hardware name: HP ProLiant DL360 Gen9/ProLiant DL360 Gen9, BIOS P89 08/12/2016 localhost kernel: Call Trace: localhost kernel: localhost kernel: dump_stack+0x9a/0xf0 localhost kernel: print_address_description.cold.3+0x9/0x23b localhost kernel: kasan_report.cold.4+0x65/0x95 localhost kernel: debug_dma_unmap_sg.part.12+0x10d/0x2d0 localhost kernel: qla2x00_bsg_sp_free+0xaf6/0x1010 [qla2xxx] Link: https://lore.kernel.org/r/20210329085229.4367-6-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Saurav Kashyap Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen [ commit 2ce35c0821afc2acd5ee1c3f60d149f8b2520ce8 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9405 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_bsg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_bsg.c b/qla2x00t-32gbit/qla_bsg.c index 8989c7ad5..78cd590a6 100644 --- a/qla2x00t-32gbit/qla_bsg.c +++ b/qla2x00t-32gbit/qla_bsg.c @@ -50,10 +50,11 @@ void qla2x00_bsg_job_done(srb_t *sp, int res) #endif struct fc_bsg_reply *bsg_reply = bsg_job->reply; + sp->free(sp); + bsg_reply->result = res; bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len); - sp->free(sp); } void qla2x00_bsg_sp_free(srb_t *sp) From c13f491f2cb303c7e53054d350ead00393fc0d10 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:33:21 +0000 Subject: [PATCH 18/29] qla2x00t-32gbit: Fix crash in qla2xxx_mqueuecommand() RIP: 0010:kmem_cache_free+0xfa/0x1b0 Call Trace: qla2xxx_mqueuecommand+0x2b5/0x2c0 [qla2xxx] scsi_queue_rq+0x5e2/0xa40 __blk_mq_try_issue_directly+0x128/0x1d0 blk_mq_request_issue_directly+0x4e/0xb0 Fix incorrect call to free srb in qla2xxx_mqueuecommand(), as srb is now allocated by upper layers. This fixes smatch warning of srb unintended free. Link: https://lore.kernel.org/r/20210329085229.4367-7-njavali@marvell.com Fixes: af2a0c51b120 ("scsi: qla2xxx: Fix SRB leak on switch command timeout") Cc: stable@vger.kernel.org # 5.5 Reported-by: Laurence Oberman Reported-by: Dan Carpenter Reviewed-by: Himanshu Madhani Signed-off-by: Arun Easi Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen [ commit 6641df81ab799f28a5d564f860233dd26cca0d93 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9406 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 1461cffe9..11a4b3cb8 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -1050,8 +1050,6 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd, if (rval != QLA_SUCCESS) { ql_dbg(ql_dbg_io + ql_dbg_verbose, vha, 0x3078, "Start scsi failed rval=%d for cmd=%p.\n", rval, cmd); - if (rval == QLA_INTERFACE_ERROR) - goto qc24_free_sp_fail_command; goto qc24_host_busy_free_sp; } @@ -1063,11 +1061,6 @@ qc24_host_busy_free_sp: qc24_target_busy: return SCSI_MLQUEUE_TARGET_BUSY; -qc24_free_sp_fail_command: - sp->free(sp); - CMD_SP(cmd) = NULL; - qla2xxx_rel_qpair_sp(sp->qpair, sp); - qc24_fail_command: cmd->scsi_done(cmd); From 75c235a15ea2240f8e0b5268b98f78d1c203b91a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:34:11 +0000 Subject: [PATCH 19/29] qla2x00t-32gbit: Fix RISC RESET completion polling After RISC RESET, the poll time for completion is too short. Fix the completion polling time. Link: https://lore.kernel.org/r/20210329085229.4367-8-njavali@marvell.com Tested-by: Laurence Oberman Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen [ commit 610d027b1e6372ffe3e85e8e095a562e920fd5cd upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9407 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 65 ++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 6 deletions(-) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 6eb22fd50..62e29e951 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -2767,6 +2767,49 @@ qla81xx_reset_mpi(scsi_qla_host_t *vha) return qla81xx_write_mpi_register(vha, mb); } +static int +qla_chk_risc_recovery(scsi_qla_host_t *vha) +{ + struct qla_hw_data *ha = vha->hw; + struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; + __le16 __iomem *mbptr = ®->mailbox0; + int i; + u16 mb[32]; + int rc = QLA_SUCCESS; + + if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) + return rc; + + /* this check is only valid after RISC reset */ + mb[0] = rd_reg_word(mbptr); + mbptr++; + if (mb[0] == 0xf) { + rc = QLA_FUNCTION_FAILED; + + for (i = 1; i < 32; i++) { + mb[i] = rd_reg_word(mbptr); + mbptr++; + } + + ql_log(ql_log_warn, vha, 0x1015, + "RISC reset failed. mb[0-7] %04xh %04xh %04xh %04xh %04xh %04xh %04xh %04xh\n", + mb[0], mb[1], mb[2], mb[3], mb[4], mb[5], mb[6], mb[7]); + ql_log(ql_log_warn, vha, 0x1015, + "RISC reset failed. mb[8-15] %04xh %04xh %04xh %04xh %04xh %04xh %04xh %04xh\n", + mb[8], mb[9], mb[10], mb[11], mb[12], mb[13], mb[14], + mb[15]); + ql_log(ql_log_warn, vha, 0x1015, + "RISC reset failed. mb[16-23] %04xh %04xh %04xh %04xh %04xh %04xh %04xh %04xh\n", + mb[16], mb[17], mb[18], mb[19], mb[20], mb[21], mb[22], + mb[23]); + ql_log(ql_log_warn, vha, 0x1015, + "RISC reset failed. mb[24-31] %04xh %04xh %04xh %04xh %04xh %04xh %04xh %04xh\n", + mb[24], mb[25], mb[26], mb[27], mb[28], mb[29], mb[30], + mb[31]); + } + return rc; +} + /** * qla24xx_reset_risc() - Perform full reset of ISP24xx RISC. * @vha: HA context @@ -2783,6 +2826,7 @@ qla24xx_reset_risc(scsi_qla_host_t *vha) uint16_t wd; static int abts_cnt; /* ISP abort retry counts */ int rval = QLA_SUCCESS; + int print = 1; spin_lock_irqsave(&ha->hardware_lock, flags); @@ -2871,17 +2915,26 @@ qla24xx_reset_risc(scsi_qla_host_t *vha) rd_reg_dword(®->hccr); wrt_reg_dword(®->hccr, HCCRX_CLR_RISC_RESET); + mdelay(10); rd_reg_dword(®->hccr); - rd_reg_word(®->mailbox0); - for (cnt = 60; rd_reg_word(®->mailbox0) != 0 && - rval == QLA_SUCCESS; cnt--) { + wd = rd_reg_word(®->mailbox0); + for (cnt = 300; wd != 0 && rval == QLA_SUCCESS; cnt--) { barrier(); - if (cnt) - udelay(5); - else + if (cnt) { + mdelay(1); + if (print && qla_chk_risc_recovery(vha)) + print = 0; + + wd = rd_reg_word(®->mailbox0); + } else { rval = QLA_FUNCTION_TIMEOUT; + + ql_log(ql_log_warn, vha, 0x015e, + "RISC reset timeout\n"); + } } + if (rval == QLA_SUCCESS) set_bit(RISC_RDY_AFT_RESET, &ha->fw_dump_cap_flags); From 32cf6b240655581be43f5ca4cd89ee8e48b1f243 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:35:09 +0000 Subject: [PATCH 20/29] qla2x00t-32gbit: Fix crash in PCIe error handling BUG: unable to handle kernel NULL pointer dereference at (null) IP: qla2x00_abort_isp+0x21/0x6b0 [qla2xxx] PGD 0 P4D 0 Oops: 0000 [#1] SMP PTI CPU: 0 PID: 1715 Comm: kworker/0:2 Tainted: GOE 4.12.14-122.37-default #1 SLE12-SP5 Hardware name: HPE Superdome Flex/Superdome Flex, BIOS Bundle:3.30.100 SFW:IP147.007.004.017.000.2009211957 09/21/2020 Workqueue: events aer_recover_work_func task: ffff9e399c14ca80 task.stack: ffffc1c58e4ac000 RIP: 0010:qla2x00_abort_isp+0x21/0x6b0 [qla2xxx] RSP: 0018:ffffc1c58e4afd50 EFLAGS: 00010282 RAX: 0000000000000000 RBX: ffff9e419cdef480 RCX: 0000000000000000 RDX: ffff9e399c14ca80 RSI: 0000000000000246 RDI: ffff9e419bbc27b8 RBP: ffff9e419bbc27b8 R08: 0000000000000004 R09: 00000000a0440000 R10: 0000000000000000 R11: ffff9e399416d1a0 R12: ffff9e419cdef000 R13: ffff9e3a7cfae800 R14: ffff9e3a7cfae800 R15: 00000000000000c0 FS: 0000000000000000(0000) GS:ffff9e39a0000000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 00000006cd00a005 CR4: 00000000007606f0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 PKRU: 55555554 Call Trace: qla2xxx_pci_slot_reset+0x141/0x160 [qla2xxx] report_slot_reset+0x41/0x80 ? merge_result.part.4+0x30/0x30 pci_walk_bus+0x70/0x90 pcie_do_recovery+0x1db/0x2e0 aer_recover_work_func+0xc2/0xf0 process_one_work+0x14c/0x390 Disable board_disable logic where driver resources are freed while OS is in the process of recovering the adapter. Link: https://lore.kernel.org/r/20210329085229.4367-9-njavali@marvell.com Tested-by: Laurence Oberman Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen [ commit f7a0ed479e66ab177801301a1a72c37775c40450 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9408 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_dbg.c | 16 +++- qla2x00t-32gbit/qla_def.h | 10 ++ qla2x00t-32gbit/qla_gbl.h | 3 + qla2x00t-32gbit/qla_init.c | 40 +++++--- qla2x00t-32gbit/qla_inline.h | 46 ++++++++++ qla2x00t-32gbit/qla_iocb.c | 60 ++++++++++-- qla2x00t-32gbit/qla_isr.c | 9 +- qla2x00t-32gbit/qla_mbx.c | 3 +- qla2x00t-32gbit/qla_nvme.c | 10 +- qla2x00t-32gbit/qla_os.c | 173 +++++++++++++++++++++-------------- 10 files changed, 265 insertions(+), 105 deletions(-) diff --git a/qla2x00t-32gbit/qla_dbg.c b/qla2x00t-32gbit/qla_dbg.c index 144a893e7..f2d05592c 100644 --- a/qla2x00t-32gbit/qla_dbg.c +++ b/qla2x00t-32gbit/qla_dbg.c @@ -113,8 +113,13 @@ qla27xx_dump_mpi_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram, uint32_t stat; ulong i, j, timer = 6000000; int rval = QLA_FUNCTION_FAILED; + scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); + + if (qla_pci_disconnected(vha, reg)) + return rval; + for (i = 0; i < ram_dwords; i += dwords, addr += dwords) { if (i + dwords > ram_dwords) dwords = ram_dwords - i; @@ -138,6 +143,9 @@ qla27xx_dump_mpi_ram(struct qla_hw_data *ha, uint32_t addr, uint32_t *ram, while (timer--) { udelay(5); + if (qla_pci_disconnected(vha, reg)) + return rval; + stat = rd_reg_dword(®->host_status); /* Check for pending interrupts. */ if (!(stat & HSRX_RISC_INT)) @@ -192,9 +200,13 @@ qla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, __be32 *ram, uint32_t dwords = qla2x00_gid_list_size(ha) / 4; uint32_t stat; ulong i, j, timer = 6000000; + scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); + if (qla_pci_disconnected(vha, reg)) + return rval; + for (i = 0; i < ram_dwords; i += dwords, addr += dwords) { if (i + dwords > ram_dwords) dwords = ram_dwords - i; @@ -216,8 +228,10 @@ qla24xx_dump_ram(struct qla_hw_data *ha, uint32_t addr, __be32 *ram, ha->flags.mbox_int = 0; while (timer--) { udelay(5); - stat = rd_reg_dword(®->host_status); + if (qla_pci_disconnected(vha, reg)) + return rval; + stat = rd_reg_dword(®->host_status); /* Check for pending interrupts. */ if (!(stat & HSRX_RISC_INT)) continue; diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index ac0b5f3b3..edd938e54 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -418,6 +418,7 @@ typedef union { } b; } port_id_t; #define INVALID_PORT_ID 0xFFFFFF +#define ISP_REG16_DISCONNECT 0xFFFF static inline le_id_t be_id_to_le(be_id_t id) { @@ -3884,6 +3885,13 @@ struct qla_hw_data_stat { u32 num_mpi_reset; }; +/* refer to pcie_do_recovery reference */ +typedef enum { + QLA_PCI_RESUME, + QLA_PCI_ERR_DETECTED, + QLA_PCI_MMIO_ENABLED, + QLA_PCI_SLOT_RESET, +} pci_error_state_t; /* * Qlogic host adapter specific data structure. */ @@ -4634,6 +4642,7 @@ struct qla_hw_data { #define DEFAULT_ZIO_THRESHOLD 5 struct qla_hw_data_stat stat; + pci_error_state_t pci_error_state; }; struct active_regions { @@ -4754,6 +4763,7 @@ typedef struct scsi_qla_host { #define FX00_CRITEMP_RECOVERY 25 #define FX00_HOST_INFO_RESEND 26 #define QPAIR_ONLINE_CHECK_NEEDED 27 +#define DO_EEH_RECOVERY 28 #define DETECT_SFP_CHANGE 29 #define N2N_LOGIN_NEEDED 30 #define IOCB_WORK_ACTIVE 31 diff --git a/qla2x00t-32gbit/qla_gbl.h b/qla2x00t-32gbit/qla_gbl.h index 6c7c7a6b2..b56753ced 100644 --- a/qla2x00t-32gbit/qla_gbl.h +++ b/qla2x00t-32gbit/qla_gbl.h @@ -228,6 +228,7 @@ extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32); extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32); extern void qla2x00_disable_board_on_pci_error(struct work_struct *); +extern void qla_eeh_work(struct work_struct *); extern void qla2x00_sp_compl(srb_t *sp, int); extern void qla2xxx_qpair_sp_free_dma(srb_t *sp); extern void qla2xxx_qpair_sp_compl(srb_t *sp, int); @@ -239,6 +240,8 @@ int qla24xx_post_relogin_work(struct scsi_qla_host *vha); void qla2x00_wait_for_sess_deletion(scsi_qla_host_t *); void qla24xx_process_purex_rdp(struct scsi_qla_host *vha, struct purex_item *pkt); +void qla_pci_set_eeh_busy(struct scsi_qla_host *); +void qla_schedule_eeh_work(struct scsi_qla_host *); /* * Global Functions in qla_mid.c source file. diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 62e29e951..be671fcfc 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -6932,22 +6932,18 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) } spin_unlock_irqrestore(&ha->vport_slock, flags); - if (!ha->flags.eeh_busy) { - /* Make sure for ISP 82XX IO DMA is complete */ - if (IS_P3P_TYPE(ha)) { - qla82xx_chip_reset_cleanup(vha); - ql_log(ql_log_info, vha, 0x00b4, - "Done chip reset cleanup.\n"); + /* Make sure for ISP 82XX IO DMA is complete */ + if (IS_P3P_TYPE(ha)) { + qla82xx_chip_reset_cleanup(vha); + ql_log(ql_log_info, vha, 0x00b4, + "Done chip reset cleanup.\n"); - /* Done waiting for pending commands. - * Reset the online flag. - */ - vha->flags.online = 0; - } - - /* Requeue all commands in outstanding command list. */ - qla2x00_abort_all_cmds(vha, DID_RESET << 16); + /* Done waiting for pending commands. Reset online flag */ + vha->flags.online = 0; } + + /* Requeue all commands in outstanding command list. */ + qla2x00_abort_all_cmds(vha, DID_RESET << 16); /* memory barrier */ wmb(); } @@ -6978,6 +6974,12 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) if (vha->hw->flags.port_isolated) return status; + if (qla2x00_isp_reg_stat(ha)) { + ql_log(ql_log_info, vha, 0x803f, + "ISP Abort - ISP reg disconnect, exiting.\n"); + return status; + } + if (test_and_clear_bit(ISP_ABORT_TO_ROM, &vha->dpc_flags)) { ha->flags.chip_reset_done = 1; vha->flags.online = 1; @@ -7017,8 +7019,18 @@ qla2x00_abort_isp(scsi_qla_host_t *vha) ha->isp_ops->get_flash_version(vha, req->ring); + if (qla2x00_isp_reg_stat(ha)) { + ql_log(ql_log_info, vha, 0x803f, + "ISP Abort - ISP reg disconnect pre nvram config, exiting.\n"); + return status; + } ha->isp_ops->nvram_config(vha); + if (qla2x00_isp_reg_stat(ha)) { + ql_log(ql_log_info, vha, 0x803f, + "ISP Abort - ISP reg disconnect post nvmram config, exiting.\n"); + return status; + } if (!qla2x00_restart_isp(vha)) { clear_bit(RESET_MARKER_NEEDED, &vha->dpc_flags); diff --git a/qla2x00t-32gbit/qla_inline.h b/qla2x00t-32gbit/qla_inline.h index ca33521e2..6ad5f8a22 100644 --- a/qla2x00t-32gbit/qla_inline.h +++ b/qla2x00t-32gbit/qla_inline.h @@ -440,3 +440,49 @@ qla_put_iocbs(struct qla_qpair *qp, struct iocb_resource *iores) } iores->res_type = RESOURCE_NONE; } + +#define ISP_REG_DISCONNECT 0xffffffffU +/************************************************************************** + * qla2x00_isp_reg_stat + * + * Description: + * Read the host status register of ISP before aborting the command. + * + * Input: + * ha = pointer to host adapter structure. + * + * + * Returns: + * Either true or false. + * + * Note: Return true if there is register disconnect. + **************************************************************************/ +static inline +uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha) +{ + struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; + struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82; + + if (IS_P3P_TYPE(ha)) + return ((rd_reg_dword(®82->host_int)) == ISP_REG_DISCONNECT); + else + return ((rd_reg_dword(®->host_status)) == + ISP_REG_DISCONNECT); +} + +static inline +bool qla_pci_disconnected(struct scsi_qla_host *vha, + struct device_reg_24xx __iomem *reg) +{ + uint32_t stat; + bool ret = false; + + stat = rd_reg_dword(®->host_status); + if (stat == 0xffffffff) { + ql_log(ql_log_info, vha, 0x8041, + "detected PCI disconnect.\n"); + qla_schedule_eeh_work(vha); + ret = true; + } + return ret; +} diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index 6291aca12..a6e0e8fb4 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -1651,8 +1651,14 @@ qla24xx_start_scsi(srb_t *sp) 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); + if (IS_SHADOW_REG_CAPABLE(ha)) { + cnt = *req->out_ptr; + } else { + cnt = rd_reg_dword_relaxed(req->req_q_out); + if (qla2x00_check_reg16_for_disconnect(vha, cnt)) + goto queuing_error; + } + if (req->ring_index < cnt) req->cnt = cnt - req->ring_index; else @@ -1848,8 +1854,13 @@ qla24xx_dif_start_scsi(srb_t *sp) 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); + if (IS_SHADOW_REG_CAPABLE(ha)) { + cnt = *req->out_ptr; + } else { + cnt = rd_reg_dword_relaxed(req->req_q_out); + if (qla2x00_check_reg16_for_disconnect(vha, cnt)) + goto queuing_error; + } if (req->ring_index < cnt) req->cnt = cnt - req->ring_index; else @@ -1928,6 +1939,7 @@ queuing_error: qla_put_iocbs(sp->qpair, &sp->iores); spin_unlock_irqrestore(&ha->hardware_lock, flags); + return QLA_FUNCTION_FAILED; } @@ -1997,8 +2009,14 @@ qla2xxx_start_scsi_mq(srb_t *sp) 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); + if (IS_SHADOW_REG_CAPABLE(ha)) { + cnt = *req->out_ptr; + } else { + cnt = rd_reg_dword_relaxed(req->req_q_out); + if (qla2x00_check_reg16_for_disconnect(vha, cnt)) + goto queuing_error; + } + if (req->ring_index < cnt) req->cnt = cnt - req->ring_index; else @@ -2209,8 +2227,14 @@ qla2xxx_dif_start_scsi_mq(srb_t *sp) 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); + if (IS_SHADOW_REG_CAPABLE(ha)) { + cnt = *req->out_ptr; + } else { + cnt = rd_reg_dword_relaxed(req->req_q_out); + if (qla2x00_check_reg16_for_disconnect(vha, cnt)) + goto queuing_error; + } + if (req->ring_index < cnt) req->cnt = cnt - req->ring_index; else @@ -2287,6 +2311,7 @@ queuing_error: qla_put_iocbs(sp->qpair, &sp->iores); spin_unlock_irqrestore(&qpair->qp_lock, flags); + return QLA_FUNCTION_FAILED; } @@ -2331,6 +2356,11 @@ __qla2x00_alloc_iocbs(struct qla_qpair *qpair, srb_t *sp) cnt = qla2x00_debounce_register( ISP_REQ_Q_OUT(ha, ®->isp)); + if (!qpair->use_shadow_reg && cnt == ISP_REG16_DISCONNECT) { + qla_schedule_eeh_work(vha); + return NULL; + } + if (req->ring_index < cnt) req->cnt = cnt - req->ring_index; else @@ -3758,6 +3788,9 @@ qla2x00_start_sp(srb_t *sp) void *pkt; unsigned long flags; + if (vha->hw->flags.eeh_busy) + return -EIO; + spin_lock_irqsave(qp->qp_lock_ptr, flags); pkt = __qla2x00_alloc_iocbs(sp->qpair, sp); if (!pkt) { @@ -3979,8 +4012,14 @@ qla2x00_start_bidir(srb_t *sp, struct scsi_qla_host *vha, uint32_t tot_dsds) /* Check for room on request queue. */ if (req->cnt < req_cnt + 2) { - cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr : - rd_reg_dword_relaxed(req->req_q_out); + if (IS_SHADOW_REG_CAPABLE(ha)) { + cnt = *req->out_ptr; + } else { + cnt = rd_reg_dword_relaxed(req->req_q_out); + if (qla2x00_check_reg16_for_disconnect(vha, cnt)) + goto queuing_error; + } + if (req->ring_index < cnt) req->cnt = cnt - req->ring_index; else @@ -4019,5 +4058,6 @@ qla2x00_start_bidir(srb_t *sp, struct scsi_qla_host *vha, uint32_t tot_dsds) qla2x00_start_iocbs(vha, req); queuing_error: spin_unlock_irqrestore(&ha->hardware_lock, flags); + return rval; } diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index 1edb2276d..674fd3658 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -282,12 +282,7 @@ qla2x00_check_reg32_for_disconnect(scsi_qla_host_t *vha, uint32_t reg) if (!test_and_set_bit(PFLG_DISCONNECTED, &vha->pci_flags) && !test_bit(PFLG_DRIVER_REMOVING, &vha->pci_flags) && !test_bit(PFLG_DRIVER_PROBING, &vha->pci_flags)) { - /* - * Schedule this (only once) on the default system - * workqueue so that all the adapter workqueues and the - * DPC thread can be shutdown cleanly. - */ - schedule_work(&vha->hw->board_disable); + qla_schedule_eeh_work(vha); } return true; } else @@ -1669,8 +1664,6 @@ global_port_update: case MBA_TEMPERATURE_ALERT: ql_dbg(ql_dbg_async, vha, 0x505e, "TEMPERATURE ALERT: %04x %04x %04x\n", mb[1], mb[2], mb[3]); - if (mb[1] == 0x12) - schedule_work(&ha->board_disable); break; case MBA_TRANS_INSERT: diff --git a/qla2x00t-32gbit/qla_mbx.c b/qla2x00t-32gbit/qla_mbx.c index 06c99963b..0149f84cd 100644 --- a/qla2x00t-32gbit/qla_mbx.c +++ b/qla2x00t-32gbit/qla_mbx.c @@ -161,7 +161,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) /* check if ISP abort is active and return cmd with timeout */ if ((test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) || test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) || - test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) && + test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) || + ha->flags.eeh_busy) && !is_rom_cmd(mcp->mb[0])) { ql_log(ql_log_info, vha, 0x1005, "Cmd 0x%x aborted with timeout since ISP Abort is pending\n", diff --git a/qla2x00t-32gbit/qla_nvme.c b/qla2x00t-32gbit/qla_nvme.c index f6f8e6738..726b185c1 100644 --- a/qla2x00t-32gbit/qla_nvme.c +++ b/qla2x00t-32gbit/qla_nvme.c @@ -411,8 +411,13 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp) } req_cnt = qla24xx_calc_iocbs(vha, tot_dsds); if (req->cnt < (req_cnt + 2)) { - cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr : - rd_reg_dword_relaxed(req->req_q_out); + if (IS_SHADOW_REG_CAPABLE(ha)) { + cnt = *req->out_ptr; + } else { + cnt = rd_reg_dword_relaxed(req->req_q_out); + if (qla2x00_check_reg16_for_disconnect(vha, cnt)) + goto queuing_error; + } if (req->ring_index < cnt) req->cnt = cnt - req->ring_index; @@ -549,6 +554,7 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp) queuing_error: spin_unlock_irqrestore(&qpair->qp_lock, flags); + return rval; } diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 11a4b3cb8..67d1f788d 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -1008,6 +1008,13 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd, goto qc24_fail_command; } + if (!qpair->online) { + ql_dbg(ql_dbg_io, vha, 0x3077, + "qpair not online. eeh_busy=%d.\n", ha->flags.eeh_busy); + cmd->result = DID_NO_CONNECT << 16; + goto qc24_fail_command; + } + if (!fcport || fcport->deleted) { cmd->result = DID_IMM_RETRY << 16; goto qc24_fail_command; @@ -1237,35 +1244,6 @@ qla2x00_wait_for_chip_reset(scsi_qla_host_t *vha) return return_status; } -#define ISP_REG_DISCONNECT 0xffffffffU -/************************************************************************** -* qla2x00_isp_reg_stat -* -* Description: -* Read the host status register of ISP before aborting the command. -* -* Input: -* ha = pointer to host adapter structure. -* -* -* Returns: -* Either true or false. -* -* Note: Return true if there is register disconnect. -**************************************************************************/ -static inline -uint32_t qla2x00_isp_reg_stat(struct qla_hw_data *ha) -{ - struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; - struct device_reg_82xx __iomem *reg82 = &ha->iobase->isp82; - - if (IS_P3P_TYPE(ha)) - return ((rd_reg_dword(®82->host_int)) == ISP_REG_DISCONNECT); - else - return ((rd_reg_dword(®->host_status)) == - ISP_REG_DISCONNECT); -} - /************************************************************************** * qla2xxx_eh_abort * @@ -1299,6 +1277,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) if (qla2x00_isp_reg_stat(ha)) { ql_log(ql_log_info, vha, 0x8042, "PCI/Register disconnect, exiting.\n"); + qla_pci_set_eeh_busy(vha); return FAILED; } @@ -1492,6 +1471,7 @@ qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) if (qla2x00_isp_reg_stat(ha)) { ql_log(ql_log_info, vha, 0x803e, "PCI/Register disconnect, exiting.\n"); + qla_pci_set_eeh_busy(vha); return FAILED; } @@ -1508,6 +1488,7 @@ qla2xxx_eh_target_reset(struct scsi_cmnd *cmd) if (qla2x00_isp_reg_stat(ha)) { ql_log(ql_log_info, vha, 0x803f, "PCI/Register disconnect, exiting.\n"); + qla_pci_set_eeh_busy(vha); return FAILED; } @@ -1543,6 +1524,7 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) if (qla2x00_isp_reg_stat(ha)) { ql_log(ql_log_info, vha, 0x8040, "PCI/Register disconnect, exiting.\n"); + qla_pci_set_eeh_busy(vha); return FAILED; } @@ -1620,7 +1602,7 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) if (qla2x00_isp_reg_stat(ha)) { ql_log(ql_log_info, vha, 0x8041, "PCI/Register disconnect, exiting.\n"); - schedule_work(&ha->board_disable); + qla_pci_set_eeh_busy(vha); return SUCCESS; } @@ -6720,6 +6702,9 @@ qla2x00_do_dpc(void *data) schedule(); + if (test_and_clear_bit(DO_EEH_RECOVERY, &base_vha->dpc_flags)) + qla_pci_set_eeh_busy(base_vha); + if (!base_vha->flags.init_done || ha->flags.mbox_busy) goto end_loop; @@ -7436,6 +7421,8 @@ static void qla_pci_error_cleanup(scsi_qla_host_t *vha) int i; unsigned long flags; + ql_dbg(ql_dbg_aer, vha, 0x9000, + "%s\n", __func__); ha->chip_reset++; ha->base_qpair->chip_reset = ha->chip_reset; @@ -7445,28 +7432,16 @@ static void qla_pci_error_cleanup(scsi_qla_host_t *vha) ha->base_qpair->chip_reset; } - /* purge MBox commands */ - if (atomic_read(&ha->num_pend_mbx_stage3)) { - clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); - complete(&ha->mbx_intr_comp); - } - - i = 0; - - while (atomic_read(&ha->num_pend_mbx_stage3) || - atomic_read(&ha->num_pend_mbx_stage2) || - atomic_read(&ha->num_pend_mbx_stage1)) { - msleep(20); - i++; - if (i > 50) - break; - } - - ha->flags.purge_mbox = 0; + /* + * purge mailbox might take a while. Slot Reset/chip reset + * will take care of the purge + */ mutex_lock(&ha->mq_lock); + ha->base_qpair->online = 0; list_for_each_entry(qpair, &base_vha->qp_list, qp_list_elem) qpair->online = 0; + wmb(); mutex_unlock(&ha->mq_lock); qla2x00_mark_all_devices_lost(vha); @@ -7503,14 +7478,17 @@ qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) { scsi_qla_host_t *vha = pci_get_drvdata(pdev); struct qla_hw_data *ha = vha->hw; + pci_ers_result_t ret = PCI_ERS_RESULT_NEED_RESET; - ql_dbg(ql_dbg_aer, vha, 0x9000, - "PCI error detected, state %x.\n", state); + ql_log(ql_log_warn, vha, 0x9000, + "PCI error detected, state %x.\n", state); + ha->pci_error_state = QLA_PCI_ERR_DETECTED; if (!atomic_read(&pdev->enable_cnt)) { ql_log(ql_log_info, vha, 0xffff, "PCI device is disabled,state %x\n", state); - return PCI_ERS_RESULT_NEED_RESET; + ret = PCI_ERS_RESULT_NEED_RESET; + goto out; } switch (state) { @@ -7520,11 +7498,12 @@ qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) set_bit(QPAIR_ONLINE_CHECK_NEEDED, &vha->dpc_flags); qla2xxx_wake_dpc(vha); } - return PCI_ERS_RESULT_CAN_RECOVER; + ret = PCI_ERS_RESULT_CAN_RECOVER; + break; case pci_channel_io_frozen: - ha->flags.eeh_busy = 1; - qla_pci_error_cleanup(vha); - return PCI_ERS_RESULT_NEED_RESET; + qla_pci_set_eeh_busy(vha); + ret = PCI_ERS_RESULT_NEED_RESET; + break; case pci_channel_io_perm_failure: ha->flags.pci_channel_io_perm_failure = 1; qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16); @@ -7532,9 +7511,12 @@ qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) set_bit(QPAIR_ONLINE_CHECK_NEEDED, &vha->dpc_flags); qla2xxx_wake_dpc(vha); } - return PCI_ERS_RESULT_DISCONNECT; + ret = PCI_ERS_RESULT_DISCONNECT; } - return PCI_ERS_RESULT_NEED_RESET; +out: + ql_dbg(ql_dbg_aer, vha, 0x600d, + "PCI error detected returning [%x].\n", ret); + return ret; } static pci_ers_result_t @@ -7548,6 +7530,10 @@ qla2xxx_pci_mmio_enabled(struct pci_dev *pdev) struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24; + ql_log(ql_log_warn, base_vha, 0x9000, + "mmio enabled\n"); + + ha->pci_error_state = QLA_PCI_MMIO_ENABLED; if (IS_QLA82XX(ha)) return PCI_ERS_RESULT_RECOVERED; @@ -7571,10 +7557,11 @@ qla2xxx_pci_mmio_enabled(struct pci_dev *pdev) ql_log(ql_log_info, base_vha, 0x9003, "RISC paused -- mmio_enabled, Dumping firmware.\n"); qla2xxx_dump_fw(base_vha); - - return PCI_ERS_RESULT_NEED_RESET; - } else - return PCI_ERS_RESULT_RECOVERED; + } + /* set PCI_ERS_RESULT_NEED_RESET to trigger call to qla2xxx_pci_slot_reset */ + ql_dbg(ql_dbg_aer, base_vha, 0x600d, + "mmio enabled returning.\n"); + return PCI_ERS_RESULT_NEED_RESET; } static pci_ers_result_t @@ -7586,9 +7573,10 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev) int rc; struct qla_qpair *qpair = NULL; - ql_dbg(ql_dbg_aer, base_vha, 0x9004, - "Slot Reset.\n"); + ql_log(ql_log_warn, base_vha, 0x9004, + "Slot Reset.\n"); + ha->pci_error_state = QLA_PCI_SLOT_RESET; /* Workaround: qla2xxx driver which access hardware earlier * needs error state to be pci_channel_io_online. * Otherwise mailbox command timesout. @@ -7622,16 +7610,24 @@ qla2xxx_pci_slot_reset(struct pci_dev *pdev) qpair->online = 1; mutex_unlock(&ha->mq_lock); + ha->flags.eeh_busy = 0; base_vha->flags.online = 1; set_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); - if (ha->isp_ops->abort_isp(base_vha) == QLA_SUCCESS) - ret = PCI_ERS_RESULT_RECOVERED; + ha->isp_ops->abort_isp(base_vha); clear_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags); + if (qla2x00_isp_reg_stat(ha)) { + ha->flags.eeh_busy = 1; + qla_pci_error_cleanup(base_vha); + ql_log(ql_log_warn, base_vha, 0x9005, + "Device unable to recover from PCI error.\n"); + } else { + ret = PCI_ERS_RESULT_RECOVERED; + } exit_slot_reset: ql_dbg(ql_dbg_aer, base_vha, 0x900e, - "slot_reset return %x.\n", ret); + "Slot Reset returning %x.\n", ret); return ret; } @@ -7643,16 +7639,55 @@ qla2xxx_pci_resume(struct pci_dev *pdev) struct qla_hw_data *ha = base_vha->hw; int ret; - ql_dbg(ql_dbg_aer, base_vha, 0x900f, - "pci_resume.\n"); + ql_log(ql_log_warn, base_vha, 0x900f, + "Pci Resume.\n"); - ha->flags.eeh_busy = 0; ret = qla2x00_wait_for_hba_online(base_vha); if (ret != QLA_SUCCESS) { ql_log(ql_log_fatal, base_vha, 0x9002, "The device failed to resume I/O from slot/link_reset.\n"); } + ha->pci_error_state = QLA_PCI_RESUME; + ql_dbg(ql_dbg_aer, base_vha, 0x600d, + "Pci Resume returning.\n"); +} + +void qla_pci_set_eeh_busy(struct scsi_qla_host *vha) +{ + struct qla_hw_data *ha = vha->hw; + struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); + bool do_cleanup = false; + unsigned long flags; + + if (ha->flags.eeh_busy) + return; + + spin_lock_irqsave(&base_vha->work_lock, flags); + if (!ha->flags.eeh_busy) { + ha->flags.eeh_busy = 1; + do_cleanup = true; + } + spin_unlock_irqrestore(&base_vha->work_lock, flags); + + if (do_cleanup) + qla_pci_error_cleanup(base_vha); +} + +/* + * this routine will schedule a task to pause IO from interrupt context + * if caller sees a PCIE error event (register read = 0xf's) + */ +void qla_schedule_eeh_work(struct scsi_qla_host *vha) +{ + struct qla_hw_data *ha = vha->hw; + struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); + + if (ha->flags.eeh_busy) + return; + + set_bit(DO_EEH_RECOVERY, &base_vha->dpc_flags); + qla2xxx_wake_dpc(base_vha); } #if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) From a1459dfdf677bda988ef2a0170f68b4af7055328 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:46:24 +0000 Subject: [PATCH 21/29] qla2x00t-32gbit: Fix mailbox recovery during PCIe error For the mailbox thread that encounters a PCIe error, pause that thread until PCIe link reset/recovery has completed to prevent the thread from possibly unmapping any type of DMA resource that might be in progress. Link: https://lore.kernel.org/r/20210329085229.4367-10-njavali@marvell.com Tested-by: Laurence Oberman Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen [ commit daafc8d33ff62009e52225106f1a6c20fe1b6ccd upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9409 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_mbx.c | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/qla2x00t-32gbit/qla_mbx.c b/qla2x00t-32gbit/qla_mbx.c index 0149f84cd..0bcd8afdc 100644 --- a/qla2x00t-32gbit/qla_mbx.c +++ b/qla2x00t-32gbit/qla_mbx.c @@ -102,7 +102,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) int rval, i; unsigned long flags = 0; device_reg_t *reg; - uint8_t abort_active; + uint8_t abort_active, eeh_delay; uint8_t io_lock_on; uint16_t command = 0; uint16_t *iptr; @@ -136,7 +136,7 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) "PCI error, exiting.\n"); return QLA_FUNCTION_TIMEOUT; } - + eeh_delay = 0; reg = ha->iobase; io_lock_on = base_vha->flags.init_done; @@ -159,11 +159,10 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) } /* check if ISP abort is active and return cmd with timeout */ - if ((test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) || - test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) || - test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags) || - ha->flags.eeh_busy) && - !is_rom_cmd(mcp->mb[0])) { + if (((test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) || + test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) || + test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) && + !is_rom_cmd(mcp->mb[0])) || ha->flags.eeh_busy) { ql_log(ql_log_info, vha, 0x1005, "Cmd 0x%x aborted with timeout since ISP Abort is pending\n", mcp->mb[0]); @@ -186,7 +185,11 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) return QLA_FUNCTION_TIMEOUT; } atomic_dec(&ha->num_pend_mbx_stage1); - if (ha->flags.purge_mbox || chip_reset != ha->chip_reset) { + if (ha->flags.purge_mbox || chip_reset != ha->chip_reset || + ha->flags.eeh_busy) { + ql_log(ql_log_warn, vha, 0xd035, + "Error detected: purge[%d] eeh[%d] cmd=0x%x, Exiting.\n", + ha->flags.purge_mbox, ha->flags.eeh_busy, mcp->mb[0]); rval = QLA_ABORTED; goto premature_exit; } @@ -266,6 +269,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) if (!wait_for_completion_timeout(&ha->mbx_intr_comp, mcp->tov * HZ)) { if (chip_reset != ha->chip_reset) { + eeh_delay = ha->flags.eeh_busy ? 1 : 0; + spin_lock_irqsave(&ha->hardware_lock, flags); ha->flags.mbox_busy = 0; spin_unlock_irqrestore(&ha->hardware_lock, @@ -283,6 +288,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) } else if (ha->flags.purge_mbox || chip_reset != ha->chip_reset) { + eeh_delay = ha->flags.eeh_busy ? 1 : 0; + spin_lock_irqsave(&ha->hardware_lock, flags); ha->flags.mbox_busy = 0; spin_unlock_irqrestore(&ha->hardware_lock, flags); @@ -324,6 +331,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) while (!ha->flags.mbox_int) { if (ha->flags.purge_mbox || chip_reset != ha->chip_reset) { + eeh_delay = ha->flags.eeh_busy ? 1 : 0; + spin_lock_irqsave(&ha->hardware_lock, flags); ha->flags.mbox_busy = 0; spin_unlock_irqrestore(&ha->hardware_lock, @@ -532,7 +541,8 @@ qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); /* Allow next mbx cmd to come in. */ complete(&ha->mbx_cmd_comp); - if (ha->isp_ops->abort_isp(vha)) { + if (ha->isp_ops->abort_isp(vha) && + !ha->flags.eeh_busy) { /* Failed. retry later. */ set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); @@ -585,6 +595,17 @@ mbx_done: ql_dbg(ql_dbg_mbx, base_vha, 0x1021, "Done %s.\n", __func__); } + i = 500; + while (i && eeh_delay && (ha->pci_error_state < QLA_PCI_SLOT_RESET)) { + /* + * The caller of this mailbox encounter pci error. + * Hold the thread until PCIE link reset complete to make + * sure caller does not unmap dma while recovery is + * in progress. + */ + msleep(1); + i--; + } return rval; } From 9c93b6642788aa3ad58b862339b40b0cbf230453 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:48:58 +0000 Subject: [PATCH 22/29] qla2x00t-32gbit: Update default AER debug mask Use PCIe AER debug mask as default. Link: https://lore.kernel.org/r/20210329085229.4367-11-njavali@marvell.com Tested-by: Laurence Oberman Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen [ commit 1cbcc531d01f813e6a93cefdc7476f858ff2b301 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9410 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_dbg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_dbg.h b/qla2x00t-32gbit/qla_dbg.h index 2e59e75c6..9eb708e5e 100644 --- a/qla2x00t-32gbit/qla_dbg.h +++ b/qla2x00t-32gbit/qla_dbg.h @@ -308,7 +308,7 @@ struct qla2xxx_fw_dump { }; #define QL_MSGHDR "qla2xxx" -#define QL_DBG_DEFAULT1_MASK 0x1e400000 +#define QL_DBG_DEFAULT1_MASK 0x1e600000 #define ql_log_fatal 0 /* display fatal errors */ #define ql_log_warn 1 /* display critical errors */ From 9bebb84e546b365acaa0a95e75ff7391256e73c2 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:49:53 +0000 Subject: [PATCH 23/29] qla2x00t-32gbit: Do logout even if fabric scan retries got exhausted Perform logout of all remote ports so that all I/Os with driver are requeued with midlayer for retry. Link: https://lore.kernel.org/r/20210329085229.4367-12-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Quinn Tran Signed-off-by: Saurav Kashyap Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen [ commit 022a2d211ce0eb410a2f4d0d0903a5ddf7687b55 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9411 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_gs.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/qla2x00t-32gbit/qla_gs.c b/qla2x00t-32gbit/qla_gs.c index 8e126afe6..5b6e04a91 100644 --- a/qla2x00t-32gbit/qla_gs.c +++ b/qla2x00t-32gbit/qla_gs.c @@ -3443,6 +3443,10 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) list_for_each_entry(fcport, &vha->vp_fcports, list) { if ((fcport->flags & FCF_FABRIC_DEVICE) != 0) { fcport->scan_state = QLA_FCPORT_SCAN; + if (fcport->loop_id == FC_NO_LOOP_ID) + fcport->logout_on_delete = 0; + else + fcport->logout_on_delete = 1; } } goto login_logout; From bd0814b79bb4fabb939f10a987e30c349b91ab9a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:50:35 +0000 Subject: [PATCH 24/29] qla2x00t-32gbit: Update version to 10.02.00.106-k Link: https://lore.kernel.org/r/20210329085229.4367-13-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen [ subject 10d91a15f26e76aec9e6fed31df7e8065f40770f upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9412 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 72c648442..da11829fa 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.105-k" +#define QLA2XXX_VERSION "10.02.00.106-k" #define QLA_DRIVER_MAJOR_VER 10 #define QLA_DRIVER_MINOR_VER 2 #define QLA_DRIVER_PATCH_VER 0 -#define QLA_DRIVER_BETA_VER 105 +#define QLA_DRIVER_BETA_VER 106 From e91874d860b2938d61237d9637e48f5eb9a28fc9 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:51:21 +0000 Subject: [PATCH 25/29] qla2x00t-32gbit: Remove unneeded if-null-free check Eliminate the following coccicheck warning: drivers/scsi/qla2xxx/qla_os.c:4622:2-7: WARNING: NULL check before some freeing functions is not needed. drivers/scsi/qla2xxx/qla_os.c:4637:3-8: WARNING: NULL check before some freeing functions is not needed. Link: https://lore.kernel.org/r/20210409120925.7122-1-linqiheng@huawei.com Reviewed-by: Himanshu Madhani Signed-off-by: Qiheng Lin Signed-off-by: Martin K. Petersen [ commit efd2617100d9c6a49c8cd27160a2353b04844d78 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9413 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 67d1f788d..6061a7593 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -4666,8 +4666,7 @@ qla2x00_free_fw_dump(struct qla_hw_data *ha) dma_free_coherent(&ha->pdev->dev, EFT_SIZE, ha->eft, ha->eft_dma); - if (ha->fw_dump) - vfree(ha->fw_dump); + vfree(ha->fw_dump); ha->fce = NULL; ha->fce_dma = 0; @@ -4681,8 +4680,7 @@ qla2x00_free_fw_dump(struct qla_hw_data *ha) ha->fw_dump_len = 0; for (j = 0; j < 2; j++, fwdt++) { - if (fwdt->template) - vfree(fwdt->template); + vfree(fwdt->template); fwdt->template = NULL; fwdt->length = 0; } From db187fc60479e75fed022e8cec1e87b5c7e39eb5 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:52:16 +0000 Subject: [PATCH 26/29] qla2x00t-32gbit: Reuse existing error handling path There is no need to duplicate code, use the existing error handling path to free resources. This is more future-proof. Link: https://lore.kernel.org/r/6973844a1532ec2dc8e86f3533362e79d78ed774.1618132821.git.christophe.jaillet@wanadoo.fr Reviewed-by: Bart Van Assche Signed-off-by: Christophe JAILLET Signed-off-by: Martin K. Petersen [ commit 5dc3468888f8ba54c3a2fdd38b13288f6b8daed2 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9414 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_bsg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_bsg.c b/qla2x00t-32gbit/qla_bsg.c index 78cd590a6..aa991c86c 100644 --- a/qla2x00t-32gbit/qla_bsg.c +++ b/qla2x00t-32gbit/qla_bsg.c @@ -2727,8 +2727,8 @@ qla2x00_get_host_stats(struct bsg_job *bsg_job) data = kzalloc(response_len, GFP_KERNEL); if (!data) { - kfree(req_data); - return -ENOMEM; + ret = -ENOMEM; + goto host_stat_out; } ret = qla2xxx_get_ini_stats(fc_bsg_to_shost(bsg_job), req_data->stat_type, From 143ea24dc73bf488ad8495f5cb8dd4e90b73f226 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:57:50 +0000 Subject: [PATCH 27/29] qla2x00t-32gbit: Reserve extra IRQ vectors Commit a6dcfe08487e ("scsi: qla2xxx: Limit interrupt vectors to number of CPUs") lowers the number of allocated MSI-X vectors to the number of CPUs. That breaks vector allocation assumptions in qla83xx_iospace_config(), qla24xx_enable_msix() and qla2x00_iospace_config(). Either of the functions computes maximum number of qpairs as: ha->max_qpairs = ha->msix_count - 1 (MB interrupt) - 1 (default response queue) - 1 (ATIO, in dual or pure target mode) max_qpairs is set to zero in case of two CPUs and initiator mode. The number is then used to allocate ha->queue_pair_map inside qla2x00_alloc_queues(). No allocation happens and ha->queue_pair_map is left NULL but the driver thinks there are queue pairs available. qla2xxx_queuecommand() tries to find a qpair in the map and crashes: if (ha->mqenable) { uint32_t tag; uint16_t hwq; struct qla_qpair *qpair = NULL; tag = blk_mq_unique_tag(cmd->request); hwq = blk_mq_unique_tag_to_hwq(tag); qpair = ha->queue_pair_map[hwq]; # <- HERE if (qpair) return qla2xxx_mqueuecommand(host, cmd, qpair); } BUG: kernel NULL pointer dereference, address: 0000000000000000 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: 0000 [#1] SMP PTI CPU: 0 PID: 72 Comm: kworker/u4:3 Tainted: G W 5.10.0-rc1+ #25 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.0.0-prebuilt.qemu-project.org 04/01/2014 Workqueue: scsi_wq_7 fc_scsi_scan_rport [scsi_transport_fc] RIP: 0010:qla2xxx_queuecommand+0x16b/0x3f0 [qla2xxx] Call Trace: scsi_queue_rq+0x58c/0xa60 blk_mq_dispatch_rq_list+0x2b7/0x6f0 ? __sbitmap_get_word+0x2a/0x80 __blk_mq_sched_dispatch_requests+0xb8/0x170 blk_mq_sched_dispatch_requests+0x2b/0x50 __blk_mq_run_hw_queue+0x49/0xb0 __blk_mq_delay_run_hw_queue+0xfb/0x150 blk_mq_sched_insert_request+0xbe/0x110 blk_execute_rq+0x45/0x70 __scsi_execute+0x10e/0x250 scsi_probe_and_add_lun+0x228/0xda0 __scsi_scan_target+0xf4/0x620 ? __pm_runtime_resume+0x4f/0x70 scsi_scan_target+0x100/0x110 fc_scsi_scan_rport+0xa1/0xb0 [scsi_transport_fc] process_one_work+0x1ea/0x3b0 worker_thread+0x28/0x3b0 ? process_one_work+0x3b0/0x3b0 kthread+0x112/0x130 ? kthread_park+0x80/0x80 ret_from_fork+0x22/0x30 The driver should allocate enough vectors to provide every CPU it's own HW queue and still handle reserved (MB, RSP, ATIO) interrupts. The change fixes the crash on dual core VM and prevents unbalanced QP allocation where nr_hw_queues is two less than the number of CPUs. Link: https://lore.kernel.org/r/20210412165740.39318-1-r.bolshakov@yadro.com Fixes: a6dcfe08487e ("scsi: qla2xxx: Limit interrupt vectors to number of CPUs") Cc: Daniel Wagner Cc: Himanshu Madhani Cc: Quinn Tran Cc: Nilesh Javali Cc: Martin K. Petersen Cc: stable@vger.kernel.org # 5.11+ Reported-by: Aleksandr Volkov Reported-by: Aleksandr Miloserdov Reviewed-by: Daniel Wagner Reviewed-by: Himanshu Madhani Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen [ commit f02d4086a8f36a0e1aaebf559b54cf24a177a486 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9415 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_isr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index 674fd3658..443ed5bed 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -4102,11 +4102,11 @@ 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, - min((u16)ha->msix_count, (u16)num_online_cpus()), + min((u16)ha->msix_count, (u16)(num_online_cpus() + min_vecs)), PCI_IRQ_MSIX); } else ret = pci_alloc_irq_vectors_affinity(ha->pdev, min_vecs, - min((u16)ha->msix_count, (u16)num_online_cpus()), + min((u16)ha->msix_count, (u16)(num_online_cpus() + min_vecs)), PCI_IRQ_MSIX | PCI_IRQ_AFFINITY, &desc); #endif From 6ddd2170c9e1d9e1cc1f930099ae229e0f074929 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:58:36 +0000 Subject: [PATCH 28/29] qla2x00t-32gbit: Add marginal path handling support Add support for eh_should_retry_cmd callback in qla2xxx host template. Link: https://lore.kernel.org/r/20210427050914.7270-1-njavali@marvell.com Reviewed-by: Himanshu Madhani Signed-off-by: Bikash Hazarika Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen [ commit 000e68faefe6240ea2e4c98b606c594b20974fb7 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9416 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 1 + 1 file changed, 1 insertion(+) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 6061a7593..7fc147b68 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -7793,6 +7793,7 @@ struct scsi_host_template qla2xxx_driver_template = { .eh_timed_out = fc_eh_timed_out, #endif .eh_abort_handler = qla2xxx_eh_abort, + .eh_should_retry_cmd = fc_eh_should_retry_cmd, .eh_device_reset_handler = qla2xxx_eh_device_reset, .eh_target_reset_handler = qla2xxx_eh_target_reset, .eh_bus_reset_handler = qla2xxx_eh_bus_reset, From 9a9fdf179fb9eeec8b04cd32a6514bb67fddd16e Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 15 May 2021 22:59:36 +0000 Subject: [PATCH 29/29] qla2x00t-32gbit: Prevent PRLI in target mode In a case when the initiator in P2P mode by some circumstances does not send PRLI, the target, in a case when the target port's WWPN is less than initiator's, changes the discovery state in DSC_GNL. When gnl completes it sends PRLI to the initiator. Usually the initiator in P2P mode always sends PRLI. We caught this issue on Linux stable v5.4.6 https://www.spinics.net/lists/stable/msg458515.html. Fix this particular corner case in the behaviour of the P2P mod target login state machine. Link: https://lore.kernel.org/r/20210422153414.4022-1-a.kovaleva@yadro.com Fixes: a9ed06d4e640 ("scsi: qla2xxx: Allow PLOGI in target mode") Reviewed-by: Roman Bolshakov Reviewed-by: Himanshu Madhani Signed-off-by: Anastasia Kovaleva Signed-off-by: Martin K. Petersen [ commit fcb16d9a8ecf1e9bfced0fc654ea4e2caa7517f4 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@9417 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 be671fcfc..7a0832e8e 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -1195,6 +1195,9 @@ static int qla24xx_post_prli_work(struct scsi_qla_host *vha, fc_port_t *fcport) { struct qla_work_evt *e; + if (vha->host->active_mode == MODE_TARGET) + return QLA_FUNCTION_FAILED; + e = qla2x00_alloc_work(vha, QLA_EVT_PRLI); if (!e) return QLA_FUNCTION_FAILED;