From c312bb71c76fef54a8b38e4915e04bedb7481098 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:14:57 +0000 Subject: [PATCH 01/57] scst_vdisk: Change 'static const char *' into 'static const char *const' This patch addresses a checkpatch complaint. git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8701 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scst/src/dev_handlers/scst_vdisk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index e333a7b16..7e320d069 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -10134,7 +10134,7 @@ static const struct attribute *vcdrom_attrs[] = { NULL, }; -static const char *cdrom_add_dev_params[] = { +static const char *const cdrom_add_dev_params[] = { "tst", NULL, }; From 2a757086d40ba36e3d825a85237e79a51036a0ce Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:15:35 +0000 Subject: [PATCH 02/57] scripts/checkpatch: Ignore the iscsi-scst/usr directory git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8702 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- scripts/checkpatch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/checkpatch b/scripts/checkpatch index d9519526c..4a388b5e3 100755 --- a/scripts/checkpatch +++ b/scripts/checkpatch @@ -10,4 +10,4 @@ ignore=( SPDX_LICENSE_TAG SYMBOLIC_PERMS ) -../linux-kernel/scripts/checkpatch.pl -f --show-types --ignore="$(echo "${ignore[@]}" | sed 's/ /,/g')" $(list-source-files | grep -vE 'fcst/linux-patches|patch$|pdf$|png$|^ibmvstgt/|^mpt/|^qla_isp/|^mvsas_tgt/') | sed 's/^#[0-9]*: FILE: \(.*\):/\1:1:/' +../linux-kernel/scripts/checkpatch.pl -f --show-types --ignore="$(echo "${ignore[@]}" | sed 's/ /,/g')" $(list-source-files | grep -vE 'fcst/linux-patches|patch$|pdf$|png$|^ibmvstgt/|^iscsi-scst/usr|^mpt/|^qla_isp/|^mvsas_tgt/') | sed 's/^#[0-9]*: FILE: \(.*\):/\1:1:/' From fcf0141902dbd2129f295def7ba87d5914de4f2a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:16:16 +0000 Subject: [PATCH 03/57] qla2x00t-32gbit: Remove redundant assignment to pointer 'host' The pointer 'host' is being initialized with a value that is never read and is being re-assigned a little later on. The assignment is redundant and hence can be removed. Link: https://lore.kernel.org/r/20190905134229.21194-1-colin.king@canonical.com Addresses-Coverity: ("Unused value") Signed-off-by: Colin Ian King Signed-off-by: Martin K. Petersen [ commit da6d2965dbdb480f091c42f54a09abe8056282e5 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8703 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_target.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index b8847d06e..099c0de63 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -476,7 +476,7 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha, case IMMED_NOTIFY_TYPE: { - struct scsi_qla_host *host = vha; + struct scsi_qla_host *host; struct imm_ntfy_from_isp *entry = (struct imm_ntfy_from_isp *)pkt; From e783a511daf03fde4c0e0dda582ea60c76906137 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:17:20 +0000 Subject: [PATCH 04/57] qla2x00t-32gbit: Dual FCP-NVMe target port support Some storage arrays advertise FCP LUNs and NVMe namespaces behind the same WWN. The driver now offers a user option by way of NVRAM parameter to allow users to choose, on a per port basis, the kind of FC-4 type they would like to prioritize for login. Link: https://lore.kernel.org/r/20190912180918.6436-9-hmadhani@marvell.com Signed-off-by: Michael Hernandez Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit 84ed362ac40ca44dbbbebf767301463aa72bc797 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8704 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 26 +++++++++++++-- qla2x00t-32gbit/qla_fw.h | 2 ++ qla2x00t-32gbit/qla_gs.c | 42 +++++++++++++---------- qla2x00t-32gbit/qla_init.c | 64 +++++++++++++++++++++--------------- qla2x00t-32gbit/qla_inline.h | 12 +++++++ qla2x00t-32gbit/qla_mbx.c | 11 ++++--- qla2x00t-32gbit/qla_os.c | 17 +++++----- 7 files changed, 114 insertions(+), 60 deletions(-) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index 257f5701d..f009e04bb 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -2303,7 +2303,7 @@ typedef struct { uint8_t fabric_port_name[WWN_SIZE]; uint16_t fp_speed; uint8_t fc4_type; - uint8_t fc4f_nvme; /* nvme fc4 feature bits */ + uint8_t fc4_features; } sw_info_t; /* FCP-4 types */ @@ -2472,7 +2472,7 @@ typedef struct fc_port { u32 supported_classes; uint8_t fc4_type; - uint8_t fc4f_nvme; + uint8_t fc4_features; uint8_t scan_state; unsigned long last_queue_full; @@ -2503,6 +2503,9 @@ typedef struct fc_port { u16 n2n_chip_reset; } fc_port_t; +#define FC4_PRIORITY_NVME 0 +#define FC4_PRIORITY_FCP 1 + #define QLA_FCPORT_SCAN 1 #define QLA_FCPORT_FOUND 2 @@ -4318,6 +4321,8 @@ struct qla_hw_data { atomic_t nvme_active_aen_cnt; uint16_t nvme_last_rptd_aen; /* Last recorded aen count */ + uint8_t fc4_type_priority; + atomic_t zio_threshold; uint16_t last_zio_threshold; @@ -4843,6 +4848,23 @@ struct sff_8247_a0 { ha->current_topology == ISP_CFG_N || \ !ha->current_topology) +#define NVME_TYPE(fcport) \ + (fcport->fc4_type & FS_FC4TYPE_NVME) \ + +#define FCP_TYPE(fcport) \ + (fcport->fc4_type & FS_FC4TYPE_FCP) \ + +#define NVME_ONLY_TARGET(fcport) \ + (NVME_TYPE(fcport) && !FCP_TYPE(fcport)) \ + +#define NVME_FCP_TARGET(fcport) \ + (FCP_TYPE(fcport) && NVME_TYPE(fcport)) \ + +#define NVME_TARGET(ha, fcport) \ + ((NVME_FCP_TARGET(fcport) && \ + (ha->fc4_type_priority == FC4_PRIORITY_NVME)) || \ + NVME_ONLY_TARGET(fcport)) \ + #include "qla_target.h" #include "qla_gbl.h" #include "qla_dbg.h" diff --git a/qla2x00t-32gbit/qla_fw.h b/qla2x00t-32gbit/qla_fw.h index fad7bd0ad..3d9df80c4 100644 --- a/qla2x00t-32gbit/qla_fw.h +++ b/qla2x00t-32gbit/qla_fw.h @@ -2113,4 +2113,6 @@ struct qla_fcp_prio_cfg { #define FA_FLASH_LAYOUT_ADDR_83 (0x3F1000/4) #define FA_FLASH_LAYOUT_ADDR_28 (0x11000/4) +#define NVRAM_DUAL_FCP_NVME_FLAG_OFFSET 0x196 + #endif diff --git a/qla2x00t-32gbit/qla_gs.c b/qla2x00t-32gbit/qla_gs.c index 5298ed100..5b5ac09f3 100644 --- a/qla2x00t-32gbit/qla_gs.c +++ b/qla2x00t-32gbit/qla_gs.c @@ -248,7 +248,7 @@ qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport) WWN_SIZE); fcport->fc4_type = (ct_rsp->rsp.ga_nxt.fc4_types[2] & BIT_0) ? - FC4_TYPE_FCP_SCSI : FC4_TYPE_OTHER; + FS_FC4TYPE_FCP : FC4_TYPE_OTHER; if (ct_rsp->rsp.ga_nxt.port_type != NS_N_PORT_TYPE && ct_rsp->rsp.ga_nxt.port_type != NS_NL_PORT_TYPE) @@ -2887,7 +2887,7 @@ qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list) struct ct_sns_req *ct_req; struct ct_sns_rsp *ct_rsp; struct qla_hw_data *ha = vha->hw; - uint8_t fcp_scsi_features = 0; + uint8_t fcp_scsi_features = 0, nvme_features = 0; struct ct_arg arg; for (i = 0; i < ha->max_fibre_devices; i++) { @@ -2933,14 +2933,19 @@ qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list) ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET]; fcp_scsi_features &= 0x0f; - if (fcp_scsi_features) - list[i].fc4_type = FC4_TYPE_FCP_SCSI; - else - list[i].fc4_type = FC4_TYPE_OTHER; + if (fcp_scsi_features) { + list[i].fc4_type = FS_FC4TYPE_FCP; + list[i].fc4_features = fcp_scsi_features; + } - list[i].fc4f_nvme = + nvme_features = ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET]; - list[i].fc4f_nvme &= 0xf; + nvme_features &= 0xf; + + if (nvme_features) { + list[i].fc4_type |= FS_FC4TYPE_NVME; + list[i].fc4_features = nvme_features; + } } /* Last device exit. */ @@ -3435,6 +3440,8 @@ void qla24xx_async_gffid_sp_done(srb_t *sp, int res) fc_port_t *fcport = sp->fcport; struct ct_sns_rsp *ct_rsp; struct event_arg ea; + uint8_t fc4_scsi_feat; + uint8_t fc4_nvme_feat; ql_dbg(ql_dbg_disc, vha, 0x2133, "Async done-%s res %x ID %x. %8phC\n", @@ -3442,24 +3449,25 @@ void qla24xx_async_gffid_sp_done(srb_t *sp, int res) fcport->flags &= ~FCF_ASYNC_SENT; ct_rsp = &fcport->ct_desc.ct_sns->p.rsp; + fc4_scsi_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET]; + fc4_nvme_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET]; + /* * FC-GS-7, 5.2.3.12 FC-4 Features - format * The format of the FC-4 Features object, as defined by the FC-4, * Shall be an array of 4-bit values, one for each type code value */ if (!res) { - if (ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET] & 0xf) { + if (fc4_scsi_feat & 0xf) { /* w1 b00:03 */ - fcport->fc4_type = - ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET]; - fcport->fc4_type &= 0xf; - } + fcport->fc4_type = FS_FC4TYPE_FCP; + fcport->fc4_features = fc4_scsi_feat & 0xf; + } - if (ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET] & 0xf) { + if (fc4_nvme_feat & 0xf) { /* w5 [00:03]/28h */ - fcport->fc4f_nvme = - ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET]; - fcport->fc4f_nvme &= 0xf; + fcport->fc4_type |= FS_FC4TYPE_NVME; + fcport->fc4_features = fc4_nvme_feat & 0xf; } } diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index d05a409c2..c1004d475 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -327,7 +327,7 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport, else lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI; - if (fcport->fc4f_nvme) + if (NVME_TARGET(vha->hw, fcport)) lio->u.logio.flags |= SRB_LOGIN_SKIP_PRLI; ql_dbg(ql_dbg_disc, vha, 0x2072, @@ -725,19 +725,17 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha, loop_id = le16_to_cpu(e->nport_handle); loop_id = (loop_id & 0x7fff); - if (fcport->fc4f_nvme) + if (NVME_TARGET(vha->hw, fcport)) current_login_state = e->current_login_state >> 4; else current_login_state = e->current_login_state & 0xf; - ql_dbg(ql_dbg_disc, vha, 0x20e2, - "%s found %8phC CLS [%x|%x] nvme %d ID[%02x%02x%02x|%02x%02x%02x] lid[%d|%d]\n", + "%s found %8phC CLS [%x|%x] fc4_type %d ID[%06x|%06x] lid[%d|%d]\n", __func__, fcport->port_name, e->current_login_state, fcport->fw_login_state, - fcport->fc4f_nvme, id.b.domain, id.b.area, id.b.al_pa, - fcport->d_id.b.domain, fcport->d_id.b.area, - fcport->d_id.b.al_pa, loop_id, fcport->loop_id); + fcport->fc4_type, id.b24, fcport->d_id.b24, + loop_id, fcport->loop_id); switch (fcport->disc_state) { case DSC_DELETE_PEND: @@ -1224,13 +1222,13 @@ qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport) sp->done = qla2x00_async_prli_sp_done; lio->u.logio.flags = 0; - if (fcport->fc4f_nvme) + if (NVME_TARGET(vha->hw, 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", fcport->port_name, sp->handle, fcport->loop_id, fcport->d_id.b24, - fcport->login_retry, fcport->fc4f_nvme ? "nvme" : "fc"); + fcport->login_retry, NVME_TARGET(vha->hw, fcport) ? "nvme" : "fc"); rval = qla2x00_start_sp(sp); if (rval != QLA_SUCCESS) { @@ -1381,14 +1379,14 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea) fcport->flags &= ~FCF_ASYNC_SENT; ql_dbg(ql_dbg_disc, vha, 0x20d2, - "%s %8phC DS %d LS %d nvme %x rc %d\n", __func__, fcport->port_name, - fcport->disc_state, pd->current_login_state, fcport->fc4f_nvme, - ea->rc); + "%s %8phC DS %d LS %d fc4_type %x rc %d\n", __func__, + fcport->port_name, fcport->disc_state, pd->current_login_state, + fcport->fc4_type, ea->rc); if (fcport->disc_state == DSC_DELETE_PEND) return; - if (fcport->fc4f_nvme) + if (NVME_TARGET(vha->hw, fcport)) ls = pd->current_login_state >> 4; else ls = pd->current_login_state & 0xf; @@ -1577,7 +1575,8 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport) ql_dbg(ql_dbg_disc, vha, 0x2118, "%s %d %8phC post %s PRLI\n", __func__, __LINE__, fcport->port_name, - fcport->fc4f_nvme ? "NVME" : "FC"); + NVME_TARGET(vha->hw, fcport) ? "NVME" : + "FC"); qla24xx_post_prli_work(vha, fcport); } break; @@ -1859,13 +1858,22 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea) break; } - if (ea->fcport->fc4f_nvme) { + /* + * Retry PRLI with other FC-4 type if failure occurred on dual + * FCP/NVMe port + */ + if (NVME_FCP_TARGET(ea->fcport)) { + 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 post fc4 prli\n", - __func__, __LINE__, ea->fcport->port_name); - ea->fcport->fc4f_nvme = 0; + "%s %d %8phC post %s prli\n", + __func__, __LINE__, ea->fcport->port_name, + (ea->fcport->fc4_type & FS_FC4TYPE_NVME) ? + "NVMe" : "FCP"); qla24xx_post_prli_work(vha, ea->fcport); - return; + break; } /* at this point both PRLI NVME & PRLI FCP failed */ @@ -1951,7 +1959,7 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) * force a relogin attempt via implicit LOGO, PLOGI, and PRLI * requests. */ - if (ea->fcport->fc4f_nvme) { + if (NVME_TARGET(vha->hw, ea->fcport)) { ql_dbg(ql_dbg_disc, vha, 0x2117, "%s %d %8phC post prli\n", __func__, __LINE__, ea->fcport->port_name); @@ -5381,7 +5389,7 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) qla2x00_iidma_fcport(vha, fcport); - if (fcport->fc4f_nvme) { + if (NVME_TARGET(vha->hw, fcport)) { qla_nvme_register_remote(vha, fcport); fcport->disc_state = DSC_LOGIN_COMPLETE; qla2x00_set_fcport_state(fcport, FCS_ONLINE); @@ -5709,11 +5717,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) new_fcport->fc4_type = swl[swl_idx].fc4_type; new_fcport->nvme_flag = 0; - new_fcport->fc4f_nvme = 0; if (vha->flags.nvme_enabled && - swl[swl_idx].fc4f_nvme) { - new_fcport->fc4f_nvme = - swl[swl_idx].fc4f_nvme; + swl[swl_idx].fc4_type & FS_FC4TYPE_NVME) { ql_log(ql_log_info, vha, 0x2131, "FOUND: NVME port %8phC as FC Type 28h\n", new_fcport->port_name); @@ -5769,7 +5774,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) /* Bypass ports whose FCP-4 type is not FCP_SCSI */ if (ql2xgffidenable && - (new_fcport->fc4_type != FC4_TYPE_FCP_SCSI && + (!(new_fcport->fc4_type & FS_FC4TYPE_FCP) && new_fcport->fc4_type != FC4_TYPE_UNKNOWN)) continue; @@ -5838,7 +5843,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) break; } - if (fcport->fc4f_nvme) { + if (NVME_TARGET(vha->hw, fcport)) { if (fcport->disc_state == DSC_DELETE_PEND) { fcport->disc_state = DSC_GNL; vha->fcport_count--; @@ -8513,6 +8518,11 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) /* N2N: driver will initiate Login instead of FW */ icb->firmware_options_3 |= BIT_8; + /* Determine NVMe/FCP priority for target ports */ + ha->fc4_type_priority = qla2xxx_get_fc4_priority(vha); + ql_log(ql_log_info, vha, 0xffff, "FC4 priority set to %s\n", + ha->fc4_type_priority & BIT_0 ? "FCP" : "NVMe"); + if (rval) { ql_log(ql_log_warn, vha, 0x0076, "NVRAM configuration failed.\n"); diff --git a/qla2x00t-32gbit/qla_inline.h b/qla2x00t-32gbit/qla_inline.h index 94eac1ab6..3bedf71ea 100644 --- a/qla2x00t-32gbit/qla_inline.h +++ b/qla2x00t-32gbit/qla_inline.h @@ -315,3 +315,15 @@ qla_83xx_start_iocbs(struct qla_qpair *qpair) WRT_REG_DWORD(req->req_q_in, req->ring_index); } + +static inline int +qla2xxx_get_fc4_priority(struct scsi_qla_host *vha) +{ + uint32_t data; + + data = + ((uint8_t *)vha->hw->nvram)[NVRAM_DUAL_FCP_NVME_FLAG_OFFSET]; + + + return ((data >> 6) & BIT_0); +} diff --git a/qla2x00t-32gbit/qla_mbx.c b/qla2x00t-32gbit/qla_mbx.c index 4a1f21c11..04175c91a 100644 --- a/qla2x00t-32gbit/qla_mbx.c +++ b/qla2x00t-32gbit/qla_mbx.c @@ -1932,7 +1932,7 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, fc_port_t *fcport, uint8_t opt) pd24 = (struct port_database_24xx *) pd; /* Check for logged in state. */ - if (fcport->fc4f_nvme) { + if (NVME_TARGET(ha, fcport)) { current_login_state = pd24->current_login_state >> 4; last_login_state = pd24->last_login_state >> 4; } else { @@ -3899,8 +3899,9 @@ 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->fc4f_nvme = 1; + fcport->fc4_type |= FS_FC4TYPE_NVME; switch (fcport->disc_state) { case DSC_DELETED: @@ -6362,7 +6363,7 @@ int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, uint64_t zero = 0; u8 current_login_state, last_login_state; - if (fcport->fc4f_nvme) { + if (NVME_TARGET(vha->hw, fcport)) { current_login_state = pd->current_login_state >> 4; last_login_state = pd->last_login_state >> 4; } else { @@ -6397,8 +6398,8 @@ int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, fcport->d_id.b.al_pa = pd->port_id[2]; fcport->d_id.b.rsvd_1 = 0; - if (fcport->fc4f_nvme) { - fcport->port_type = 0; + if (NVME_TARGET(vha->hw, fcport)) { + fcport->port_type = FCT_NVME; if ((pd->prli_svc_param_word_3[0] & BIT_5) == 0) fcport->port_type |= FCT_NVME_INITIATOR; if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 6adb393d4..9b1e0a458 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -5096,19 +5096,17 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e) fcport->d_id = e->u.new_sess.id; fcport->flags |= FCF_FABRIC_DEVICE; fcport->fw_login_state = DSC_LS_PLOGI_PEND; - if (e->u.new_sess.fc4_type == FS_FC4TYPE_FCP) - fcport->fc4_type = FC4_TYPE_FCP_SCSI; - - if (e->u.new_sess.fc4_type == FS_FC4TYPE_NVME) { - fcport->fc4_type = FC4_TYPE_OTHER; - fcport->fc4f_nvme = FC4_TYPE_NVME; - } memcpy(fcport->port_name, e->u.new_sess.port_name, WWN_SIZE); - if (e->u.new_sess.fc4_type & FS_FCP_IS_N2N) + fcport->fc4_type = e->u.new_sess.fc4_type; + if (e->u.new_sess.fc4_type & FS_FCP_IS_N2N) { + fcport->fc4_type = FS_FC4TYPE_FCP; fcport->n2n_flag = 1; + if (vha->flags.nvme_enabled) + fcport->fc4_type |= FS_FC4TYPE_NVME; + } } else { ql_dbg(ql_dbg_disc, vha, 0xffff, @@ -5212,7 +5210,8 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e) fcport->flags &= ~FCF_FABRIC_DEVICE; fcport->keep_nport_handle = 1; if (vha->flags.nvme_enabled) { - fcport->fc4f_nvme = 1; + fcport->fc4_type = + (FS_FC4TYPE_NVME | FS_FC4TYPE_FCP); fcport->n2n_flag = 1; } fcport->fw_login_state = 0; From db78f0ff56ec70029c45ee1ea008c09c3b7a7046 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:17:45 +0000 Subject: [PATCH 05/57] qla2x00t-32gbit: Add error handling for PLOGI ELS passthrough Add error handling logic to ELS Passthrough relating to NVME devices. Current code does not parse error code to take proper recovery action, instead it re-logins with the same login parameters that encountered the error. Ex: nport handle collision. Link: https://lore.kernel.org/r/20190912180918.6436-10-hmadhani@marvell.com Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen vha; struct event_arg ea; struct qla_work_evt *e; + struct fc_port *conflict_fcport; + port_id_t cid; /* conflict Nport id */ + u32 *fw_status = sp->u.iocb_cmd.u.els_plogi.fw_status; + u16 lid; ql_dbg(ql_dbg_disc, vha, 0x3072, "%s ELS done rc %d hdl=%x, portid=%06x %8phC\n", @@ -2757,14 +2761,99 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res) if (sp->flags & SRB_WAKEUP_ON_COMP) complete(&lio->u.els_plogi.comp); else { - if (res) { - set_bit(RELOGIN_NEEDED, &vha->dpc_flags); - } else { + switch (fw_status[0]) { + case CS_DATA_UNDERRUN: + case CS_COMPLETE: memset(&ea, 0, sizeof(ea)); ea.fcport = fcport; ea.data[0] = MBS_COMMAND_COMPLETE; ea.sp = sp; qla24xx_handle_plogi_done_event(vha, &ea); + break; + case CS_IOCB_ERROR: + switch (fw_status[1]) { + case LSC_SCODE_PORTID_USED: + lid = fw_status[2] & 0xffff; + qlt_find_sess_invalidate_other(vha, + wwn_to_u64(fcport->port_name), + fcport->d_id, lid, &conflict_fcport); + if (conflict_fcport) { + /* + * Another fcport shares the same + * loop_id & nport id; conflict + * fcport needs to finish cleanup + * before this fcport can proceed + * to login. + */ + conflict_fcport->conflict = fcport; + fcport->login_pause = 1; + ql_dbg(ql_dbg_disc, vha, 0x20ed, + "%s %d %8phC pid %06x inuse with lid %#x post gidpn\n", + __func__, __LINE__, + fcport->port_name, + fcport->d_id.b24, lid); + } else { + ql_dbg(ql_dbg_disc, vha, 0x20ed, + "%s %d %8phC pid %06x inuse with lid %#x sched del\n", + __func__, __LINE__, + fcport->port_name, + fcport->d_id.b24, lid); + qla2x00_clear_loop_id(fcport); + set_bit(lid, vha->hw->loop_id_map); + fcport->loop_id = lid; + fcport->keep_nport_handle = 0; + qlt_schedule_sess_for_deletion(fcport); + } + break; + + case LSC_SCODE_NPORT_USED: + cid.b.domain = (fw_status[2] >> 16) & 0xff; + cid.b.area = (fw_status[2] >> 8) & 0xff; + cid.b.al_pa = fw_status[2] & 0xff; + cid.b.rsvd_1 = 0; + + ql_dbg(ql_dbg_disc, vha, 0x20ec, + "%s %d %8phC lid %#x in use with pid %06x post gnl\n", + __func__, __LINE__, fcport->port_name, + fcport->loop_id, cid.b24); + set_bit(fcport->loop_id, + vha->hw->loop_id_map); + fcport->loop_id = FC_NO_LOOP_ID; + qla24xx_post_gnl_work(vha, fcport); + break; + + case LSC_SCODE_NOXCB: + vha->hw->exch_starvation++; + if (vha->hw->exch_starvation > 5) { + ql_log(ql_log_warn, vha, 0xd046, + "Exchange starvation. Resetting RISC\n"); + vha->hw->exch_starvation = 0; + set_bit(ISP_ABORT_NEEDED, + &vha->dpc_flags); + qla2xxx_wake_dpc(vha); + } + /* fall through */ + default: + ql_dbg(ql_dbg_disc, vha, 0x20eb, + "%s %8phC cmd error fw_status 0x%x 0x%x 0x%x\n", + __func__, sp->fcport->port_name, + fw_status[0], fw_status[1], fw_status[2]); + + fcport->flags &= ~FCF_ASYNC_SENT; + set_bit(RELOGIN_NEEDED, &vha->dpc_flags); + break; + } + break; + + default: + ql_dbg(ql_dbg_disc, vha, 0x20eb, + "%s %8phC cmd error 2 fw_status 0x%x 0x%x 0x%x\n", + __func__, sp->fcport->port_name, + fw_status[0], fw_status[1], fw_status[2]); + + sp->fcport->flags &= ~FCF_ASYNC_SENT; + set_bit(RELOGIN_NEEDED, &vha->dpc_flags); + break; } e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP); From 770a53d10dacc93d4b383a742eaa7b6c5d8307b1 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:18:09 +0000 Subject: [PATCH 06/57] qla2x00t-32gbit: Set remove flag for all VP During driver unload, the remove flag will be set for all scsi_qla_host/NPIV. This allows each NPIV to see the flag instead of reaching for base_vha to search for it. Link: https://lore.kernel.org/r/20190912180918.6436-11-hmadhani@marvell.com Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8706 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 9b1e0a458..e70b2b0a1 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -3542,6 +3542,29 @@ disable_device: return ret; } +static void __qla_set_remove_flag(scsi_qla_host_t *base_vha) +{ + scsi_qla_host_t *vp; + unsigned long flags; + struct qla_hw_data *ha; + + if (!base_vha) + return; + + ha = base_vha->hw; + + spin_lock_irqsave(&ha->vport_slock, flags); + list_for_each_entry(vp, &ha->vp_list, list) + set_bit(PFLG_DRIVER_REMOVING, &vp->pci_flags); + + /* + * Indicate device removal to prevent future board_disable + * and wait until any pending board_disable has completed. + */ + set_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags); + spin_unlock_irqrestore(&ha->vport_slock, flags); +} + static void qla2x00_shutdown(struct pci_dev *pdev) { @@ -3558,7 +3581,7 @@ qla2x00_shutdown(struct pci_dev *pdev) * Prevent future board_disable and wait * until any pending board_disable has completed. */ - set_bit(PFLG_DRIVER_REMOVING, &vha->pci_flags); + __qla_set_remove_flag(vha); cancel_work_sync(&ha->board_disable); if (!atomic_read(&pdev->enable_cnt)) @@ -3718,10 +3741,7 @@ qla2x00_remove_one(struct pci_dev *pdev) ha = base_vha->hw; ql_log(ql_log_info, base_vha, 0xb079, "Removing driver\n"); - - /* Indicate device removal to prevent future board_disable and wait - * until any pending board_disable has completed. */ - set_bit(PFLG_DRIVER_REMOVING, &base_vha->pci_flags); + __qla_set_remove_flag(base_vha); cancel_work_sync(&ha->board_disable); /* From a082f1c862152ed90c4f7aa94bf86714e063b92b Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:18:35 +0000 Subject: [PATCH 07/57] qla2x00t-32gbit: Check for MB timeout while capturing ISP27/28xx FW dump Add mailbox timeout checkout for ISP 27xx/28xx during FW dump procedure. Without the timeout check, hardware lock can be held for long period. This patch would shorten the dump procedure if a timeout condition is encountered. Link: https://lore.kernel.org/r/20190912180918.6436-12-hmadhani@marvell.com Reviewed-by: Laurence Oberman Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8707 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_tmpl.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_tmpl.c b/qla2x00t-32gbit/qla_tmpl.c index 294d77c02..b948d94c8 100644 --- a/qla2x00t-32gbit/qla_tmpl.c +++ b/qla2x00t-32gbit/qla_tmpl.c @@ -10,6 +10,7 @@ #define ISPREG(vha) (&(vha)->hw->iobase->isp24) #define IOBAR(reg) offsetof(typeof(*(reg)), iobase_addr) #define IOBASE(vha) IOBAR(ISPREG(vha)) +#define INVALID_ENTRY ((struct qla27xx_fwdt_entry *)0xffffffffffffffffUL) static inline void qla27xx_insert16(uint16_t value, void *buf, ulong *len) @@ -261,6 +262,7 @@ qla27xx_fwdt_entry_t262(struct scsi_qla_host *vha, ulong start = le32_to_cpu(ent->t262.start_addr); ulong end = le32_to_cpu(ent->t262.end_addr); ulong dwords; + int rc; ql_dbg(ql_dbg_misc, vha, 0xd206, "%s: rdram(%x) [%lx]\n", __func__, ent->t262.ram_area, *len); @@ -308,7 +310,13 @@ qla27xx_fwdt_entry_t262(struct scsi_qla_host *vha, dwords = end - start + 1; if (buf) { buf += *len; - qla24xx_dump_ram(vha->hw, start, buf, dwords, &buf); + rc = qla24xx_dump_ram(vha->hw, start, buf, dwords, &buf); + if (rc != QLA_SUCCESS) { + ql_dbg(ql_dbg_async, vha, 0xffff, + "%s: dump ram MB failed. Area %xh start %lxh end %lxh\n", + __func__, area, start, end); + return INVALID_ENTRY; + } } *len += dwords * sizeof(uint32_t); done: @@ -838,6 +846,13 @@ qla27xx_walk_template(struct scsi_qla_host *vha, ent = qla27xx_find_entry(type)(vha, ent, buf, len); if (!ent) break; + + if (ent == INVALID_ENTRY) { + *len = 0; + ql_dbg(ql_dbg_async, vha, 0xffff, + "Unable to capture FW dump"); + goto bailout; + } } if (tmp->count) @@ -847,6 +862,9 @@ qla27xx_walk_template(struct scsi_qla_host *vha, if (ent) ql_dbg(ql_dbg_misc, vha, 0xd019, "%s: missing end entry\n", __func__); + +bailout: + cpu_to_le32s(&tmp->count); /* endianize residual count */ } static void @@ -1010,7 +1028,9 @@ qla27xx_fwdump(scsi_qla_host_t *vha, int hardware_locked) } len = qla27xx_execute_fwdt_template(vha, fwdt->template, buf); - if (len != fwdt->dump_size) { + if (len == 0) { + goto bailout; + } else if (len != fwdt->dump_size) { ql_log(ql_log_warn, vha, 0xd013, "-> fwdt%u fwdump residual=%+ld\n", j, fwdt->dump_size - len); @@ -1025,6 +1045,7 @@ qla27xx_fwdump(scsi_qla_host_t *vha, int hardware_locked) qla2x00_post_uevent_work(vha, QLA_UEVENT_CODE_FW_DUMP); } +bailout: #ifndef __CHECKER__ if (!hardware_locked) spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); From 2b96536e511034061f3ca053e009ddedb7f6be05 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:19:00 +0000 Subject: [PATCH 08/57] qla2x00t-32gbit: Capture FW dump on MPI heartbeat stop event For MPI heartbeat stop Async Event, this patch would capture MPI FW dump and chip reset. FW will tell which function to capture FW dump for. Link: https://lore.kernel.org/r/20190912180918.6436-13-hmadhani@marvell.com Reviewed-by: Laurence Oberman Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8708 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_attr.c | 4 +++- qla2x00t-32gbit/qla_isr.c | 31 ++++++++++++++++++++++++++----- qla2x00t-32gbit/qla_tmpl.c | 4 +++- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/qla2x00t-32gbit/qla_attr.c b/qla2x00t-32gbit/qla_attr.c index 7259bce85..ae97e2f31 100644 --- a/qla2x00t-32gbit/qla_attr.c +++ b/qla2x00t-32gbit/qla_attr.c @@ -102,8 +102,10 @@ qla2x00_sysfs_write_fw_dump(struct file *filp, struct kobject *kobj, qla8044_idc_lock(ha); qla82xx_set_reset_owner(vha); qla8044_idc_unlock(ha); - } else + } else { + ha->fw_dump_mpi = 1; qla2x00_system_error(vha); + } break; case 4: if (IS_P3P_TYPE(ha)) { diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index 87d5c5903..b92ae486d 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -1239,11 +1239,32 @@ global_port_update: break; case MBA_IDC_AEN: - mb[4] = RD_REG_WORD(®24->mailbox4); - mb[5] = RD_REG_WORD(®24->mailbox5); - mb[6] = RD_REG_WORD(®24->mailbox6); - mb[7] = RD_REG_WORD(®24->mailbox7); - qla83xx_handle_8200_aen(vha, mb); + if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) { + ha->flags.fw_init_done = 0; + ql_log(ql_log_warn, vha, 0xffff, + "MPI Heartbeat stop. Chip reset needed. MB0[%xh] MB1[%xh] MB2[%xh] MB3[%xh]\n", + mb[0], mb[1], mb[2], mb[3]); + + if ((mb[1] & BIT_8) || + (mb[2] & BIT_8)) { + ql_log(ql_log_warn, vha, 0xd013, + "MPI Heartbeat stop. FW dump needed\n"); + ha->fw_dump_mpi = 1; + ha->isp_ops->fw_dump(vha, 1); + } + set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); + qla2xxx_wake_dpc(vha); + } else if (IS_QLA83XX(ha)) { + mb[4] = RD_REG_WORD(®24->mailbox4); + mb[5] = RD_REG_WORD(®24->mailbox5); + mb[6] = RD_REG_WORD(®24->mailbox6); + mb[7] = RD_REG_WORD(®24->mailbox7); + qla83xx_handle_8200_aen(vha, mb); + } else { + ql_dbg(ql_dbg_async, vha, 0x5052, + "skip Heartbeat processing mb0-3=[0x%04x] [0x%04x] [0x%04x] [0x%04x]\n", + mb[0], mb[1], mb[2], mb[3]); + } break; case MBA_DPORT_DIAGNOSTICS: diff --git a/qla2x00t-32gbit/qla_tmpl.c b/qla2x00t-32gbit/qla_tmpl.c index b948d94c8..5b0c057de 100644 --- a/qla2x00t-32gbit/qla_tmpl.c +++ b/qla2x00t-32gbit/qla_tmpl.c @@ -1017,8 +1017,9 @@ qla27xx_fwdump(scsi_qla_host_t *vha, int hardware_locked) uint j; ulong len; void *buf = vha->hw->fw_dump; + uint count = vha->hw->fw_dump_mpi ? 2 : 1; - for (j = 0; j < 2; j++, fwdt++, buf += len) { + for (j = 0; j < count; j++, fwdt++, buf += len) { ql_log(ql_log_warn, vha, 0xd011, "-> fwdt%u running...\n", j); if (!fwdt->template) { @@ -1046,6 +1047,7 @@ qla27xx_fwdump(scsi_qla_host_t *vha, int hardware_locked) } bailout: + vha->hw->fw_dump_mpi = 0; #ifndef __CHECKER__ if (!hardware_locked) spin_unlock_irqrestore(&vha->hw->hardware_lock, flags); From d7df645158d1478d4be01f82c94758f5642a20b8 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:19:24 +0000 Subject: [PATCH 09/57] qla2x00t-32gbit: Improve logging for scan thread Move messages to verbose logging for scan thread. Link: https://lore.kernel.org/r/20190912180918.6436-14-hmadhani@marvell.com Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8709 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_gs.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/qla2x00t-32gbit/qla_gs.c b/qla2x00t-32gbit/qla_gs.c index 5b5ac09f3..7a00272ca 100644 --- a/qla2x00t-32gbit/qla_gs.c +++ b/qla2x00t-32gbit/qla_gs.c @@ -3571,7 +3571,7 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) u8 recheck = 0; u16 dup = 0, dup_cnt = 0; - ql_dbg(ql_dbg_disc, vha, 0xffff, + ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, "%s enter\n", __func__); if (sp->gen1 != vha->hw->base_qpair->chip_reset) { @@ -3588,8 +3588,9 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); } else { - ql_dbg(ql_dbg_disc, vha, 0xffff, - "Fabric scan failed on all retries.\n"); + ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, + "%s: Fabric scan failed for %d retries.\n", + __func__, vha->scan.scan_retry); } goto out; } @@ -4055,7 +4056,7 @@ done_free_sp: void qla24xx_async_gpnft_done(scsi_qla_host_t *vha, srb_t *sp) { - ql_dbg(ql_dbg_disc, vha, 0xffff, + ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, "%s enter\n", __func__); qla24xx_async_gnnft(vha, sp, sp->gen2); } @@ -4069,7 +4070,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) u32 rspsz; unsigned long flags; - ql_dbg(ql_dbg_disc, vha, 0xffff, + ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, "%s enter\n", __func__); if (!vha->flags.online) @@ -4078,14 +4079,15 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) spin_lock_irqsave(&vha->work_lock, flags); if (vha->scan.scan_flags & SF_SCANNING) { spin_unlock_irqrestore(&vha->work_lock, flags); - ql_dbg(ql_dbg_disc, vha, 0xffff, "scan active\n"); + ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, + "%s: scan active\n", __func__); return rval; } vha->scan.scan_flags |= SF_SCANNING; spin_unlock_irqrestore(&vha->work_lock, flags); if (fc4_type == FC4_TYPE_FCP_SCSI) { - ql_dbg(ql_dbg_disc, vha, 0xffff, + ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, "%s: Performing FCP Scan\n", __func__); if (sp) @@ -4140,7 +4142,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp) } sp->u.iocb_cmd.u.ctarg.rsp_size = rspsz; - ql_dbg(ql_dbg_disc, vha, 0xffff, + ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, "%s scan list size %d\n", __func__, vha->scan.size); memset(vha->scan.l, 0, vha->scan.size); @@ -4205,8 +4207,8 @@ done_free_sp: spin_lock_irqsave(&vha->work_lock, flags); vha->scan.scan_flags &= ~SF_SCANNING; if (vha->scan.scan_flags == 0) { - ql_dbg(ql_dbg_disc, vha, 0xffff, - "%s: schedule\n", __func__); + ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, + "%s: Scan scheduled.\n", __func__); vha->scan.scan_flags |= SF_QUEUED; schedule_delayed_work(&vha->scan.scan_work, 5); } From 41781f030be927f513c7debe9fbaf581b582a966 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:19:49 +0000 Subject: [PATCH 10/57] qla2x00t-32gbit: Update driver version to 10.01.00.20-k Link: https://lore.kernel.org/r/20190912180918.6436-15-hmadhani@marvell.com Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit 8ae15a460b1471622f85bad6caebe56fd91f4f83 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8710 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_version.h b/qla2x00t-32gbit/qla_version.h index a8f2a953c..225e401b6 100644 --- a/qla2x00t-32gbit/qla_version.h +++ b/qla2x00t-32gbit/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "10.01.00.19-k" +#define QLA2XXX_VERSION "10.01.00.20-k" #define QLA_DRIVER_MAJOR_VER 10 #define QLA_DRIVER_MINOR_VER 1 From f6593f38cd0ed44651be1286acc942152812a137 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:20:14 +0000 Subject: [PATCH 11/57] qla2x00t-32gbit: Retry PLOGI on FC-NVMe PRLI failure Current code will send PRLI with FC-NVMe bit set for the targets which support only FCP. This may result into issue with targets which do not understand NVMe and will go into a strange state. This patch would restart the login process by going back to PLOGI state. The PLOGI state will force the target to respond to correct PRLI request. Fixes: c76ae845ea836 ("scsi: qla2xxx: Add error handling for PLOGI ELS passthrough") Cc: stable@vger.kernel.org # 5.4 Link: https://lore.kernel.org/r/20191105150657.8092-2-hmadhani@marvell.com Reviewed-by: Ewan D. Milne Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit 983f127603fac650fa34ee69db363e4615eaf9e7 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8711 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 37 ++++++++----------------------------- qla2x00t-32gbit/qla_iocb.c | 6 +++++- 2 files changed, 13 insertions(+), 30 deletions(-) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index c1004d475..52fb856c7 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -1863,42 +1863,21 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea) * FCP/NVMe port */ if (NVME_FCP_TARGET(ea->fcport)) { - 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 post %s prli\n", __func__, __LINE__, ea->fcport->port_name, (ea->fcport->fc4_type & FS_FC4TYPE_NVME) ? "NVMe" : "FCP"); - qla24xx_post_prli_work(vha, ea->fcport); - break; + if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME) + ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME; + else + ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP; } - /* at this point both PRLI NVME & PRLI FCP failed */ - if (N2N_TOPO(vha->hw)) { - if (ea->fcport->n2n_link_reset_cnt < 3) { - ea->fcport->n2n_link_reset_cnt++; - /* - * remote port is not sending Plogi. Reset - * link to kick start his 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 - */ - ea->fcport->flags &= ~FCF_ASYNC_SENT; - ea->fcport->keep_nport_handle = 0; - qlt_schedule_sess_for_deletion(ea->fcport); - } + 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_iocb.c b/qla2x00t-32gbit/qla_iocb.c index 616f9cb6f..61ddfe5c1 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -2770,6 +2770,7 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res) ea.sp = sp; qla24xx_handle_plogi_done_event(vha, &ea); break; + case CS_IOCB_ERROR: switch (fw_status[1]) { case LSC_SCODE_PORTID_USED: @@ -2840,6 +2841,7 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res) fw_status[0], fw_status[1], fw_status[2]); fcport->flags &= ~FCF_ASYNC_SENT; + fcport->disc_state = DSC_LOGIN_FAILED; set_bit(RELOGIN_NEEDED, &vha->dpc_flags); break; } @@ -2852,6 +2854,7 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res) fw_status[0], fw_status[1], fw_status[2]); sp->fcport->flags &= ~FCF_ASYNC_SENT; + sp->fcport->disc_state = DSC_LOGIN_FAILED; set_bit(RELOGIN_NEEDED, &vha->dpc_flags); break; } @@ -2887,11 +2890,12 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode, return -ENOMEM; } + fcport->flags |= FCF_ASYNC_SENT; + fcport->disc_state = DSC_LOGIN_PEND; elsio = &sp->u.iocb_cmd; ql_dbg(ql_dbg_io, vha, 0x3073, "Enter: PLOGI portid=%06x\n", fcport->d_id.b24); - fcport->flags |= FCF_ASYNC_SENT; sp->type = SRB_ELS_DCMD; sp->name = "ELS_DCMD"; sp->fcport = fcport; From a763c697b042a55d08043470ed1af71c17611051 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:20:38 +0000 Subject: [PATCH 12/57] qla2x00t-32gbit: Do command completion on abort timeout On switch, fabric and mgt command timeout, driver send Abort to tell FW to return the original command. If abort is timeout, then return both Abort and original command for cleanup. Fixes: 219d27d7147e0 ("scsi: qla2xxx: Fix race conditions in the code for aborting SCSI commands") Cc: stable@vger.kernel.org # 5.2 Link: https://lore.kernel.org/r/20191105150657.8092-3-hmadhani@marvell.com Reviewed-by: Ewan D. Milne Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit 71c80b75ce8f08c0978ce9a9816b81b5c3ce5e12 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8712 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 1 + qla2x00t-32gbit/qla_init.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index f009e04bb..fa7143c79 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -626,6 +626,7 @@ typedef struct srb { const char *name; int iocbs; struct qla_qpair *qpair; + struct srb *cmd_sp; struct list_head elem; u32 gen1; /* scratch */ u32 gen2; /* scratch */ diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 52fb856c7..720239cdf 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -100,8 +100,22 @@ static void qla24xx_abort_iocb_timeout(void *data) u32 handle; unsigned long flags; + if (sp->cmd_sp) + ql_dbg(ql_dbg_async, sp->vha, 0x507c, + "Abort timeout - cmd hdl=%x, cmd type=%x hdl=%x, type=%x\n", + sp->cmd_sp->handle, sp->cmd_sp->type, + sp->handle, sp->type); + else + ql_dbg(ql_dbg_async, sp->vha, 0x507c, + "Abort timeout 2 - hdl=%x, type=%x\n", + sp->handle, sp->type); + spin_lock_irqsave(qpair->qp_lock_ptr, flags); for (handle = 1; handle < qpair->req->num_outstanding_cmds; handle++) { + if (sp->cmd_sp && (qpair->req->outstanding_cmds[handle] == + sp->cmd_sp)) + qpair->req->outstanding_cmds[handle] = NULL; + /* removing the abort */ if (qpair->req->outstanding_cmds[handle] == sp) { qpair->req->outstanding_cmds[handle] = NULL; @@ -110,6 +124,9 @@ static void qla24xx_abort_iocb_timeout(void *data) } spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); + if (sp->cmd_sp) + sp->cmd_sp->done(sp->cmd_sp, QLA_OS_TIMER_EXPIRED); + abt->u.abt.comp_status = CS_TIMEOUT; sp->done(sp, QLA_OS_TIMER_EXPIRED); } @@ -141,6 +158,7 @@ static int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait) sp->type = SRB_ABT_CMD; sp->name = "abort"; sp->qpair = cmd_sp->qpair; + sp->cmd_sp = cmd_sp; if (wait) sp->flags = SRB_WAKEUP_ON_COMP; From 958e8eda7db01b8fd793da95e8366082344ee4f8 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:21:14 +0000 Subject: [PATCH 13/57] qla2x00t-32gbit: Fix SRB leak on switch command timeout when GPSC/GPDB switch command fails, driver just returns without doing a proper cleanup. This patch fixes this memory leak by calling sp->free() in the error path. Link: https://lore.kernel.org/r/20191105150657.8092-4-hmadhani@marvell.com Reviewed-by: Ewan D. Milne Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit af2a0c51b1205327f55a7e82e530403ae1d42cbb upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8713 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_gs.c | 2 +- qla2x00t-32gbit/qla_init.c | 11 +++++------ qla2x00t-32gbit/qla_mbx.c | 4 ---- qla2x00t-32gbit/qla_mid.c | 11 ++++------- qla2x00t-32gbit/qla_os.c | 7 ++++++- 5 files changed, 16 insertions(+), 19 deletions(-) diff --git a/qla2x00t-32gbit/qla_gs.c b/qla2x00t-32gbit/qla_gs.c index 7a00272ca..67230688b 100644 --- a/qla2x00t-32gbit/qla_gs.c +++ b/qla2x00t-32gbit/qla_gs.c @@ -3010,7 +3010,7 @@ static void qla24xx_async_gpsc_sp_done(srb_t *sp, int res) fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); if (res == QLA_FUNCTION_TIMEOUT) - return; + goto done; if (res == (DID_ERROR << 16)) { /* entry status error */ diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 720239cdf..55953cfbd 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -1150,19 +1150,18 @@ static void qla24xx_async_gpdb_sp_done(srb_t *sp, int res) "Async done-%s res %x, WWPN %8phC mb[1]=%x mb[2]=%x \n", sp->name, res, fcport->port_name, mb[1], mb[2]); - if (res == QLA_FUNCTION_TIMEOUT) { - dma_pool_free(sp->vha->hw->s_dma_pool, sp->u.iocb_cmd.u.mbx.in, - sp->u.iocb_cmd.u.mbx.in_dma); - return; - } - fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); + + if (res == QLA_FUNCTION_TIMEOUT) + goto done; + memset(&ea, 0, sizeof(ea)); ea.fcport = fcport; ea.sp = sp; qla24xx_handle_gpdb_event(vha, &ea); +done: dma_pool_free(ha->s_dma_pool, sp->u.iocb_cmd.u.mbx.in, sp->u.iocb_cmd.u.mbx.in_dma); diff --git a/qla2x00t-32gbit/qla_mbx.c b/qla2x00t-32gbit/qla_mbx.c index 04175c91a..0cf94f05f 100644 --- a/qla2x00t-32gbit/qla_mbx.c +++ b/qla2x00t-32gbit/qla_mbx.c @@ -6288,17 +6288,13 @@ int qla24xx_send_mb_cmd(struct scsi_qla_host *vha, mbx_cmd_t *mcp) case QLA_SUCCESS: ql_dbg(ql_dbg_mbx, vha, 0x119d, "%s: %s done.\n", __func__, sp->name); - sp->free(sp); break; default: ql_dbg(ql_dbg_mbx, vha, 0x119e, "%s: %s Failed. %x.\n", __func__, sp->name, rval); - sp->free(sp); break; } - return rval; - done_free_sp: sp->free(sp); done: diff --git a/qla2x00t-32gbit/qla_mid.c b/qla2x00t-32gbit/qla_mid.c index 238240984..eabc51271 100644 --- a/qla2x00t-32gbit/qla_mid.c +++ b/qla2x00t-32gbit/qla_mid.c @@ -946,7 +946,7 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd) sp = qla2x00_get_sp(base_vha, NULL, GFP_KERNEL); if (!sp) - goto done; + return rval; sp->type = SRB_CTRL_VP; sp->name = "ctrl_vp"; @@ -962,7 +962,7 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd) ql_dbg(ql_dbg_async, vha, 0xffff, "%s: %s Failed submission. %x.\n", __func__, sp->name, rval); - goto done_free_sp; + goto done; } ql_dbg(ql_dbg_vport, vha, 0x113f, "%s hndl %x submitted\n", @@ -980,16 +980,13 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd) case QLA_SUCCESS: ql_dbg(ql_dbg_vport, vha, 0xffff, "%s: %s done.\n", __func__, sp->name); - goto done_free_sp; + break; default: ql_dbg(ql_dbg_vport, vha, 0xffff, "%s: %s Failed. %x.\n", __func__, sp->name, rval); - goto done_free_sp; + break; } done: - return rval; - -done_free_sp: sp->free(sp); return rval; } diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index e70b2b0a1..7344caca3 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -1033,7 +1033,7 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd, 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_fail_command; + goto qc24_free_sp_fail_command; goto qc24_host_busy_free_sp; } @@ -1045,6 +1045,11 @@ 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 021c29815119350ed98756fe393e418ff6a1a969 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:21:37 +0000 Subject: [PATCH 14/57] qla2x00t-32gbit: Fix driver unload hang This patch fixes driver unload hang by removing msleep() Fixes: d74595278f4ab ("scsi: qla2xxx: Add multiple queue pair functionality.") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191105150657.8092-5-hmadhani@marvell.com Reviewed-by: Ewan D. Milne Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit dd322b7f3efc8cda085bb60eadc4aee6324eadd8 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8714 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 55953cfbd..cf4b2b04d 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -9008,8 +9008,6 @@ int qla2xxx_delete_qpair(struct scsi_qla_host *vha, struct qla_qpair *qpair) struct qla_hw_data *ha = qpair->hw; qpair->delete_in_progress = 1; - while (atomic_read(&qpair->ref_count)) - msleep(500); ret = qla25xx_delete_req_que(vha, qpair->req); if (ret != QLA_SUCCESS) From e6f87e326fdc47d0e58dcec33bbe42b089c804b2 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:22:04 +0000 Subject: [PATCH 15/57] qla2x00t-32gbit: Fix double scsi_done for abort path Current code assumes abort will remove the original command from the active list where scsi_done will not be called. Instead, the eh_abort thread will do the scsi_done. That is not the case. Instead, we have a double scsi_done calls triggering use after free. Abort will tell FW to release the command from FW possesion. The original command will return to ULP with error in its normal fashion via scsi_done. eh_abort path would wait for the original command completion before returning. eh_abort path will not perform the scsi_done call. Fixes: 219d27d7147e0 ("scsi: qla2xxx: Fix race conditions in the code for aborting SCSI commands") Cc: stable@vger.kernel.org # 5.2 Link: https://lore.kernel.org/r/20191105150657.8092-6-hmadhani@marvell.com Reviewed-by: Ewan D. Milne Signed-off-by: Quinn Tran Signed-off-by: Arun Easi Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit f45bca8c5052e8c59bab64ee90c44441678b9a52 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8715 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 5 +- qla2x00t-32gbit/qla_isr.c | 5 ++ qla2x00t-32gbit/qla_nvme.c | 4 +- qla2x00t-32gbit/qla_os.c | 128 ++++++++++++++++++------------------- 4 files changed, 74 insertions(+), 68 deletions(-) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index fa7143c79..b19c525b3 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -613,13 +613,16 @@ typedef struct srb { */ uint8_t cmd_type; uint8_t pad[3]; - atomic_t ref_count; struct kref cmd_kref; /* need to migrate ref_count over to this */ void *priv; wait_queue_head_t nvme_ls_waitq; struct fc_port *fcport; struct scsi_qla_host *vha; unsigned int start_timer:1; + unsigned int abort:1; + unsigned int aborted:1; + unsigned int completed:1; + uint32_t handle; uint16_t flags; uint16_t type; diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index b92ae486d..8a29c13e9 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -2511,6 +2511,11 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) return; } + if (sp->abort) + sp->aborted = 1; + else + sp->completed = 1; + if (sp->cmd_type != TYPE_SRB) { req->outstanding_cmds[handle] = NULL; ql_dbg(ql_dbg_io, vha, 0x3015, diff --git a/qla2x00t-32gbit/qla_nvme.c b/qla2x00t-32gbit/qla_nvme.c index 4bfb41e28..85320e615 100644 --- a/qla2x00t-32gbit/qla_nvme.c +++ b/qla2x00t-32gbit/qla_nvme.c @@ -235,8 +235,8 @@ static void qla_nvme_abort_work(struct work_struct *work) if (ha->flags.host_shutting_down) { ql_log(ql_log_info, sp->fcport->vha, 0xffff, - "%s Calling done on sp: %p, type: 0x%x, sp->ref_count: 0x%x\n", - __func__, sp, sp->type, atomic_read(&sp->ref_count)); + "%s Calling done on sp: %p, type: 0x%x\n", + __func__, sp, sp->type); sp->done(sp, 0); goto out; } diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 7344caca3..46ebf2c42 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -718,11 +718,6 @@ void qla2x00_sp_compl(srb_t *sp, int res) struct scsi_cmnd *cmd = GET_CMD_SP(sp); struct completion *comp = sp->comp; - if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0)) - return; - - atomic_dec(&sp->ref_count); - sp->free(sp); cmd->result = res; CMD_SP(cmd) = NULL; @@ -814,11 +809,6 @@ void qla2xxx_qpair_sp_compl(srb_t *sp, int res) struct scsi_cmnd *cmd = GET_CMD_SP(sp); struct completion *comp = sp->comp; - if (WARN_ON_ONCE(atomic_read(&sp->ref_count) == 0)) - return; - - atomic_dec(&sp->ref_count); - sp->free(sp); cmd->result = res; CMD_SP(cmd) = NULL; @@ -940,7 +930,7 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) sp->u.scmd.cmd = cmd; sp->type = SRB_SCSI_CMD; - atomic_set(&sp->ref_count, 1); + CMD_SP(cmd) = (void *)sp; sp->free = qla2x00_sp_free_dma; sp->done = qla2x00_sp_compl; @@ -1022,11 +1012,9 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd, sp->u.scmd.cmd = cmd; sp->type = SRB_SCSI_CMD; - atomic_set(&sp->ref_count, 1); CMD_SP(cmd) = (void *)sp; sp->free = qla2xxx_qpair_sp_free_dma; sp->done = qla2xxx_qpair_sp_compl; - sp->qpair = qpair; rval = ha->isp_ops->start_scsi_mq(sp); if (rval != QLA_SUCCESS) { @@ -1226,23 +1214,6 @@ qla2x00_wait_for_chip_reset(scsi_qla_host_t *vha) return return_status; } -static int -sp_get(struct srb *sp) -{ -#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 11, 0) - if (!atomic_inc_not_zero(&sp->ref_count)) - return ENXIO; - else - return 0; -#else - if (!refcount_inc_not_zero((refcount_t *)&sp->ref_count)) - /* kref get fail */ - return ENXIO; - else - return 0; -#endif -} - #define ISP_REG_DISCONNECT 0xffffffffU /************************************************************************** * qla2x00_isp_reg_stat @@ -1298,6 +1269,9 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) uint64_t lun; int rval; struct qla_hw_data *ha = vha->hw; + uint32_t ratov_j; + struct qla_qpair *qpair; + unsigned long flags; if (qla2x00_isp_reg_stat(ha)) { ql_log(ql_log_info, vha, 0x8042, @@ -1310,13 +1284,26 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) return ret; sp = scsi_cmd_priv(cmd); + qpair = sp->qpair; - if (sp->fcport && sp->fcport->deleted) + if ((sp->fcport && sp->fcport->deleted) || !qpair) return SUCCESS; - /* Return if the command has already finished. */ - if (sp_get(sp)) + spin_lock_irqsave(qpair->qp_lock_ptr, flags); + if (sp->completed) { + spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); return SUCCESS; + } + + if (sp->abort || sp->aborted) { + spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); + return FAILED; + } + + sp->abort = 1; + sp->comp = ∁ + spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); + id = cmd->device->id; lun = cmd->device->lun; @@ -1325,47 +1312,37 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) "Aborting from RISC nexus=%ld:%d:%llu sp=%p cmd=%p handle=%x\n", vha->host_no, id, lun, sp, cmd, sp->handle); + /* + * Abort will release the original Command/sp from FW. Let the + * original command call scsi_done. In return, he will wakeup + * this sleeping thread. + */ rval = ha->isp_ops->abort_command(sp); + ql_dbg(ql_dbg_taskm, vha, 0x8003, "Abort command mbx cmd=%p, rval=%x.\n", cmd, rval); + /* Wait for the command completion. */ + ratov_j = ha->r_a_tov/10 * 4 * 1000; + ratov_j = msecs_to_jiffies(ratov_j); switch (rval) { case QLA_SUCCESS: - /* - * The command has been aborted. That means that the firmware - * won't report a completion. - */ - sp->done(sp, DID_ABORT << 16); - ret = SUCCESS; - break; - case QLA_FUNCTION_PARAMETER_ERROR: { - /* Wait for the command completion. */ - uint32_t ratov = ha->r_a_tov/10; - uint32_t ratov_j = msecs_to_jiffies(4 * ratov * 1000); - - WARN_ON_ONCE(sp->comp); - sp->comp = ∁ if (!wait_for_completion_timeout(&comp, ratov_j)) { ql_dbg(ql_dbg_taskm, vha, 0xffff, "%s: Abort wait timer (4 * R_A_TOV[%d]) expired\n", - __func__, ha->r_a_tov); + __func__, ha->r_a_tov/10); ret = FAILED; } else { ret = SUCCESS; } break; - } default: - /* - * Either abort failed or abort and completion raced. Let - * the SCSI core retry the abort in the former case. - */ ret = FAILED; break; } sp->comp = NULL; - atomic_dec(&sp->ref_count); + ql_log(ql_log_info, vha, 0x801c, "Abort command issued nexus=%ld:%d:%llu -- %x.\n", vha->host_no, id, lun, ret); @@ -1757,32 +1734,53 @@ static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res, scsi_qla_host_t *vha = qp->vha; struct qla_hw_data *ha = vha->hw; int rval; + bool ret_cmd; + uint32_t ratov_j; - if (sp_get(sp)) + if (qla2x00_chip_is_down(vha)) { + sp->done(sp, res); return; + } if (sp->type == SRB_NVME_CMD || sp->type == SRB_NVME_LS || (sp->type == SRB_SCSI_CMD && !ha->flags.eeh_busy && !test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) && !qla2x00_isp_reg_stat(ha))) { - sp->comp = ∁ - spin_unlock_irqrestore(qp->qp_lock_ptr, *flags); - rval = ha->isp_ops->abort_command(sp); + if (sp->comp) { + sp->done(sp, res); + return; + } + sp->comp = ∁ + sp->abort = 1; + spin_unlock_irqrestore(qp->qp_lock_ptr, *flags); + + rval = ha->isp_ops->abort_command(sp); + /* Wait for command completion. */ + ret_cmd = false; + ratov_j = ha->r_a_tov/10 * 4 * 1000; + ratov_j = msecs_to_jiffies(ratov_j); switch (rval) { case QLA_SUCCESS: - sp->done(sp, res); + if (wait_for_completion_timeout(&comp, ratov_j)) { + ql_dbg(ql_dbg_taskm, vha, 0xffff, + "%s: Abort wait timer (4 * R_A_TOV[%d]) expired\n", + __func__, ha->r_a_tov/10); + ret_cmd = true; + } + /* else FW return SP to driver */ break; - case QLA_FUNCTION_PARAMETER_ERROR: - wait_for_completion(&comp); + default: + ret_cmd = true; break; } spin_lock_irqsave(qp->qp_lock_ptr, *flags); - sp->comp = NULL; + if (ret_cmd && (!sp->completed || !sp->aborted)) + sp->done(sp, res); + } else { + sp->done(sp, res); } - - atomic_dec(&sp->ref_count); } static void @@ -1804,7 +1802,6 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res) for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) { sp = req->outstanding_cmds[cnt]; if (sp) { - req->outstanding_cmds[cnt] = NULL; switch (sp->cmd_type) { case TYPE_SRB: qla2x00_abort_srb(qp, sp, res, &flags); @@ -1826,6 +1823,7 @@ __qla2x00_abort_all_cmds(struct qla_qpair *qp, int res) default: break; } + req->outstanding_cmds[cnt] = NULL; } } spin_unlock_irqrestore(qp->qp_lock_ptr, flags); From 2888c8de2e29d5b7b546b5d7b92e7309cc8772fd Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:22:26 +0000 Subject: [PATCH 16/57] qla2x00t-32gbit: Fix memory leak when sending I/O fails On heavy loads, a memory leak of the srb_t structure is observed. This would make the qla2xxx_srbs cache gobble up memory. Fixes: 219d27d7147e0 ("scsi: qla2xxx: Fix race conditions in the code for aborting SCSI commands") Cc: stable@vger.kernel.org # 5.2 Link: https://lore.kernel.org/r/20191105150657.8092-7-hmadhani@marvell.com Reviewed-by: Ewan D. Milne Signed-off-by: Arun Easi Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit 2f856d4e8c23f5ad5221f8da4a2f22d090627f19 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8716 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 46ebf2c42..dfe9deea8 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -946,6 +946,8 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) qc24_host_busy_free_sp: sp->free(sp); + CMD_SP(cmd) = NULL; + qla2x00_rel_sp(sp); qc24_target_busy: return SCSI_MLQUEUE_TARGET_BUSY; @@ -1029,6 +1031,8 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd, qc24_host_busy_free_sp: sp->free(sp); + CMD_SP(cmd) = NULL; + qla2xxx_rel_qpair_sp(sp->qpair, sp); qc24_target_busy: return SCSI_MLQUEUE_TARGET_BUSY; From 50dae0f79955339da3c830981922ff9ac19f9e5e Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:22:54 +0000 Subject: [PATCH 17/57] qla2x00t-32gbit: Fix device connect issues in P2P configuration P2P needs to take the alternate plogi route. Link: https://lore.kernel.org/r/20191105150657.8092-8-hmadhani@marvell.com Reviewed-by: Ewan D. Milne Signed-off-by: Arun Easi Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit 65e9200938052ce90f24421bb057e1be1d6147c7 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8717 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_gbl.h | 1 + qla2x00t-32gbit/qla_init.c | 9 +++++++++ qla2x00t-32gbit/qla_iocb.c | 5 ++--- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/qla2x00t-32gbit/qla_gbl.h b/qla2x00t-32gbit/qla_gbl.h index dc90f9357..afc0bb6b6 100644 --- a/qla2x00t-32gbit/qla_gbl.h +++ b/qla2x00t-32gbit/qla_gbl.h @@ -926,4 +926,5 @@ int qla2x00_set_data_rate(scsi_qla_host_t *vha, uint16_t mode); /* nvme.c */ void qla_nvme_unregister_remote_port(struct fc_port *fcport); +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 cf4b2b04d..cefd05483 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -1716,6 +1716,15 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha, qla24xx_fcport_handle_login(vha, fcport); } +void qla_handle_els_plogi_done(scsi_qla_host_t *vha, + struct event_arg *ea) +{ + ql_dbg(ql_dbg_disc, vha, 0x2118, + "%s %d %8phC post PRLI\n", + __func__, __LINE__, ea->fcport->port_name); + qla24xx_post_prli_work(vha, ea->fcport); +} + /* * RSCN(s) came in for this fcport, but the RSCN(s) was not able * to be consumed by the fcport diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index 61ddfe5c1..07caa095a 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -2766,9 +2766,8 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res) case CS_COMPLETE: memset(&ea, 0, sizeof(ea)); ea.fcport = fcport; - ea.data[0] = MBS_COMMAND_COMPLETE; - ea.sp = sp; - qla24xx_handle_plogi_done_event(vha, &ea); + ea.rc = res; + qla_handle_els_plogi_done(vha, &ea); break; case CS_IOCB_ERROR: From 7c9bf10d00536c257aa98a137d417f347816edaa Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:23:19 +0000 Subject: [PATCH 18/57] qla2x00t-32gbit: Update driver version to 10.01.00.21-k Link: https://lore.kernel.org/r/20191105150657.8092-9-hmadhani@marvell.com Reviewed-by: Ewan D. Milne Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit b3f74568411b2df0806e0d1df6458cb270eb29ce upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8718 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_version.h b/qla2x00t-32gbit/qla_version.h index 225e401b6..03bd3b712 100644 --- a/qla2x00t-32gbit/qla_version.h +++ b/qla2x00t-32gbit/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "10.01.00.20-k" +#define QLA2XXX_VERSION "10.01.00.21-k" #define QLA_DRIVER_MAJOR_VER 10 #define QLA_DRIVER_MINOR_VER 1 From 3680a3d7452d93743a14295d2dd7c60aab55f369 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:23:44 +0000 Subject: [PATCH 19/57] qla2x00t-32gbit: Fix a dma_pool_free() call This patch fixes the following kernel warning: DMA-API: qla2xxx 0000:00:0a.0: device driver frees DMA memory with different size [device address=0x00000000c7b60000] [map size=4088 bytes] [unmap size=512 bytes] WARNING: CPU: 3 PID: 1122 at kernel/dma/debug.c:1021 check_unmap+0x4d0/0xbd0 CPU: 3 PID: 1122 Comm: rmmod Tainted: G O 5.4.0-rc1-dbg+ #1 RIP: 0010:check_unmap+0x4d0/0xbd0 Call Trace: debug_dma_free_coherent+0x123/0x173 dma_free_attrs+0x76/0xe0 qla2x00_mem_free+0x329/0xc40 [qla2xxx_scst] qla2x00_free_device+0x170/0x1c0 [qla2xxx_scst] qla2x00_remove_one+0x4f0/0x6d0 [qla2xxx_scst] pci_device_remove+0xd5/0x1f0 device_release_driver_internal+0x159/0x280 driver_detach+0x8b/0xf2 bus_remove_driver+0x9a/0x15a driver_unregister+0x51/0x70 pci_unregister_driver+0x2d/0x130 qla2x00_module_exit+0x1c/0xbc [qla2xxx_scst] __x64_sys_delete_module+0x22a/0x300 do_syscall_64+0x6f/0x2e0 entry_SYSCALL_64_after_hwframe+0x49/0xbe Fixes: 3f006ac342c0 ("scsi: qla2xxx: Secure flash update support for ISP28XX") # v5.2-rc1~130^2~270. Cc: Michael Hernandez Cc: Himanshu Madhani Link: https://lore.kernel.org/r/20191106044226.5207-3-bvanassche@acm.org Reviewed-by: Martin Wilck Acked-by: Himanshu Madhani Signed-off-by: Bart Van Assche Signed-off-by: Martin K. Petersen [ commit 162b805e38327135168cb0938bd37b131b481cb0 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8719 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 dfe9deea8..52560380c 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -4743,7 +4743,8 @@ qla2x00_mem_free(struct qla_hw_data *ha) ha->sfp_data = NULL; if (ha->flt) - dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE, + dma_free_coherent(&ha->pdev->dev, + sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE, ha->flt, ha->flt_dma); ha->flt = NULL; ha->flt_dma = 0; From 6432df87e6e87dd152422db7d5dd3eea8a66616a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:24:09 +0000 Subject: [PATCH 20/57] qla2x00t-32gbit: initialize fc4_type_priority ha->fc4_type_priority is currently initialized only in qla81xx_nvram_config(). That makes it default to NVMe for other adapters. Fix it. Fixes: 84ed362ac40c ("scsi: qla2xxx: Dual FCP-NVMe target port support") Link: https://lore.kernel.org/r/20191107224839.32417-2-martin.wilck@suse.com Tested-by: David Bond Acked-by: Himanshu Madhani Reviewed-by: Bart Van Assche Signed-off-by: Martin Wilck Signed-off-by: Martin K. Petersen [ commit f5a2b219a7897751f9bb1c8d7308933e33000f2f upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8720 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index cefd05483..1dbee8800 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -2218,8 +2218,18 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha) ql_dbg(ql_dbg_init, vha, 0x0061, "Configure NVRAM parameters...\n"); + /* Let priority default to FCP, can be overridden by nvram_config */ + ha->fc4_type_priority = FC4_PRIORITY_FCP; + ha->isp_ops->nvram_config(vha); + if (ha->fc4_type_priority != FC4_PRIORITY_FCP && + ha->fc4_type_priority != FC4_PRIORITY_NVME) + ha->fc4_type_priority = FC4_PRIORITY_FCP; + + ql_log(ql_log_info, vha, 0xffff, "FC4 priority set to %s\n", + ha->fc4_type_priority == FC4_PRIORITY_FCP ? "FCP" : "NVMe"); + if (ha->flags.disable_serdes) { /* Mask HBA via NVRAM settings? */ ql_log(ql_log_info, vha, 0x0077, @@ -8525,8 +8535,6 @@ qla81xx_nvram_config(scsi_qla_host_t *vha) /* Determine NVMe/FCP priority for target ports */ ha->fc4_type_priority = qla2xxx_get_fc4_priority(vha); - ql_log(ql_log_info, vha, 0xffff, "FC4 priority set to %s\n", - ha->fc4_type_priority & BIT_0 ? "FCP" : "NVMe"); if (rval) { ql_log(ql_log_warn, vha, 0x0076, From ca0c061ed50285c2aec160f64fb245935a400a6e Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:24:31 +0000 Subject: [PATCH 21/57] qla2x00t-32gbit: don't use zero for FC4_PRIORITY_NVME Avoid an uninitialized value (0) for ha->fc4_type_priority being falsely interpreted as NVMe priority. Not strictly needed any more after the previous patch, but makes the fc4_type_priority handling more explicit. Link: https://lore.kernel.org/r/20191107224839.32417-3-martin.wilck@suse.com Tested-by: David Bond Acked-by: Himanshu Madhani Reviewed-by: Bart Van Assche Signed-off-by: Martin Wilck Signed-off-by: Martin K. Petersen [ commit a10c8803d0dbab54370eeac2a07e6540c6215908 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8721 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 6 ++++-- qla2x00t-32gbit/qla_inline.h | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index b19c525b3..7d8630cee 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -2507,8 +2507,10 @@ typedef struct fc_port { u16 n2n_chip_reset; } fc_port_t; -#define FC4_PRIORITY_NVME 0 -#define FC4_PRIORITY_FCP 1 +enum { + FC4_PRIORITY_NVME = 1, + FC4_PRIORITY_FCP = 2, +}; #define QLA_FCPORT_SCAN 1 #define QLA_FCPORT_FOUND 2 diff --git a/qla2x00t-32gbit/qla_inline.h b/qla2x00t-32gbit/qla_inline.h index 3bedf71ea..522bbf25f 100644 --- a/qla2x00t-32gbit/qla_inline.h +++ b/qla2x00t-32gbit/qla_inline.h @@ -325,5 +325,5 @@ qla2xxx_get_fc4_priority(struct scsi_qla_host *vha) ((uint8_t *)vha->hw->nvram)[NVRAM_DUAL_FCP_NVME_FLAG_OFFSET]; - return ((data >> 6) & BIT_0); + return (data >> 6) & BIT_0 ? FC4_PRIORITY_FCP : FC4_PRIORITY_NVME; } From 7da5ef65ff472cb45f40f20b3e467ac91d4af0fa Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:24:57 +0000 Subject: [PATCH 22/57] qla2x00t-32gbit: Revert "scsi: qla2xxx: Fix memory leak when sending I/O fails" This reverts commit 2f856d4e8c23f5ad5221f8da4a2f22d090627f19. This patch was found to introduce a double free regression. The issue it originally attempted to address was fixed in patch f45bca8c5052 ("scsi: qla2xxx: Fix double scsi_done for abort path"). Link: https://lore.kernel.org/r/4BDE2B95-835F-43BE-A32C-2629D7E03E0A@marvell.com Requested-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit 5a993e507ee65a28eca6690ee11868555c4ca46b upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8722 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_os.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 52560380c..5368f95ab 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -946,8 +946,6 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd) qc24_host_busy_free_sp: sp->free(sp); - CMD_SP(cmd) = NULL; - qla2x00_rel_sp(sp); qc24_target_busy: return SCSI_MLQUEUE_TARGET_BUSY; @@ -1031,8 +1029,6 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd, qc24_host_busy_free_sp: sp->free(sp); - CMD_SP(cmd) = NULL; - qla2xxx_rel_qpair_sp(sp->qpair, sp); qc24_target_busy: return SCSI_MLQUEUE_TARGET_BUSY; From 91a600d894ae94f9c923f733d8c6d083de1eb97a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:25:21 +0000 Subject: [PATCH 23/57] qla2x00t-32gbit: add module to ops template to allow module references In nvme-fc: it's possible to have connected active controllers and as no references are taken on the LLDD, the LLDD can be unloaded. The controller would enter a reconnect state and as long as the LLDD resumed within the reconnect timeout, the controller would resume. But if a namespace on the controller is the root device, allowing the driver to unload can be problematic. To reload the driver, it may require new io to the boot device, and as it's no longer connected we get into a catch-22 that eventually fails, and the system locks up. Fix this issue by taking a module reference for every connected controller (which is what the core layer did to the transport module). Reference is cleared when the controller is removed. Acked-by: Himanshu Madhani Reviewed-by: Christoph Hellwig Signed-off-by: James Smart Signed-off-by: Keith Busch [ commit 863fbae929c7a5b64e96b8a3ffb34a29eefb9f8f upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8723 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_nvme.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/qla2x00t-32gbit/qla_nvme.c b/qla2x00t-32gbit/qla_nvme.c index 85320e615..5b7f4abdc 100644 --- a/qla2x00t-32gbit/qla_nvme.c +++ b/qla2x00t-32gbit/qla_nvme.c @@ -621,6 +621,13 @@ static void qla_nvme_remoteport_delete(struct nvme_fc_remote_port *rport) } static struct nvme_fc_port_template qla_nvme_fc_transport = { +#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 5, 0) + /* + * See also commit 863fbae929c7 ("nvme_fc: add module to ops template + * to allow module references"). + */ + .module = THIS_MODULE, +#endif .localport_delete = qla_nvme_localport_delete, .remoteport_delete = qla_nvme_remoteport_delete, .create_queue = qla_nvme_alloc_queue, From 49cf31c71f7a3ef8a43afc1423d644c945a14d4e Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:25:44 +0000 Subject: [PATCH 24/57] qla2x00t-32gbit: fix rports not being mark as lost in sync fabric scan In qla2x00_find_all_fabric_devs(), fcport->flags & FCF_LOGIN_NEEDED is a necessary condition for logging into new rports, but not for dropping lost ones. Fixes: 726b85487067 ("qla2xxx: Add framework for async fabric discovery") Link: https://lore.kernel.org/r/20191122221912.20100-2-martin.wilck@suse.com Tested-by: David Bond Signed-off-by: Martin Wilck Acked-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit d341e9a8f2cffe4000c610225c629f62c7489c74 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8724 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 1dbee8800..6c28f38f8 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -5898,8 +5898,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) if (test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags)) break; - if ((fcport->flags & FCF_FABRIC_DEVICE) == 0 || - (fcport->flags & FCF_LOGIN_NEEDED) == 0) + if ((fcport->flags & FCF_FABRIC_DEVICE) == 0) continue; if (fcport->scan_state == QLA_FCPORT_SCAN) { @@ -5922,7 +5921,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) } } - if (fcport->scan_state == QLA_FCPORT_FOUND) + if (fcport->scan_state == QLA_FCPORT_FOUND && + (fcport->flags & FCF_LOGIN_NEEDED) != 0) qla24xx_fcport_handle_login(vha, fcport); } return (rval); From 5a64ee930ebcdb56b325e3bf5e216dc4c879f0e7 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:26:50 +0000 Subject: [PATCH 25/57] qla2x00t-32gbit: unregister ports after GPN_FT failure When ports are lost due to unzoning them, and the initiator port is not part of any more zones, the GPN_FT command used for the fabric scan may fail. In this case, the current code simply gives up after a few retries. But if the zone is gone, all rports should actually be marked as lost. Fix this by jumping to the code that handles logout after GNN_FT after scan retries are exhausted. Fixes: f352eeb75419 ("scsi: qla2xxx: Add ability to use GPNFT/GNNFT for RSCN handling") Link: https://lore.kernel.org/r/20191122221912.20100-3-martin.wilck@suse.com Tested-by: Jason Orendorf Signed-off-by: Martin Wilck Acked-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit c8a347931869bf4373bfd4036d297b8e11ab48ab upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8725 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_gs.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_gs.c b/qla2x00t-32gbit/qla_gs.c index 67230688b..446a9d6ba 100644 --- a/qla2x00t-32gbit/qla_gs.c +++ b/qla2x00t-32gbit/qla_gs.c @@ -3587,12 +3587,23 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) if (vha->scan.scan_retry < MAX_SCAN_RETRIES) { set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); + goto out; } else { - ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0xffff, + ql_dbg(ql_dbg_disc, vha, 0xffff, "%s: Fabric scan failed for %d retries.\n", __func__, vha->scan.scan_retry); + /* + * Unable to scan any rports. logout loop below + * will unregister all sessions. + */ + list_for_each_entry(fcport, &vha->vp_fcports, list) { + if ((fcport->flags & FCF_FABRIC_DEVICE) != 0) { + fcport->scan_state = QLA_FCPORT_SCAN; + fcport->logout_on_delete = 0; + } + } + goto login_logout; } - goto out; } vha->scan.scan_retry = 0; @@ -3670,6 +3681,7 @@ void qla24xx_async_gnnft_done(scsi_qla_host_t *vha, srb_t *sp) dup_cnt); } +login_logout: /* * Logout all previous fabric dev marked lost, except FCP2 devices. */ From 80e6db859acfcc887f8936ec2d88a670a5621d04 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:27:52 +0000 Subject: [PATCH 26/57] qla2x00t-32gbit: Fix qla2x00_request_irqs() for MSI Commit 4fa183455988 ("scsi: qla2xxx: Utilize pci_alloc_irq_vectors/ pci_free_irq_vectors calls.") use pci_alloc_irq_vectors() to replace pci_enable_msi() but it didn't handle the return value correctly. This bug make qla2x00 always fail to setup MSI if MSI-X fail, so fix it. BTW, improve the log message of return value in qla2x00_request_irqs() to avoid confusion. Fixes: 4fa183455988 ("scsi: qla2xxx: Utilize pci_alloc_irq_vectors/pci_free_irq_vectors calls.") Cc: Michael Hernandez Link: https://lore.kernel.org/r/1574314847-14280-1-git-send-email-chenhc@lemote.com Signed-off-by: Huacai Chen Acked-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit 45dc8f2d9c94ed74a5e31e63e9136a19a7e16081 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8726 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_isr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index 8a29c13e9..848216ca4 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -3763,7 +3763,7 @@ qla2x00_request_irqs(struct qla_hw_data *ha, struct rsp_que *rsp) skip_msix: ql_log(ql_log_info, vha, 0x0037, - "Falling back-to MSI mode -%d.\n", ret); + "Falling back-to MSI mode -- ret=%d.\n", ret); if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha) && !IS_QLA8001(ha) && !IS_P3P_TYPE(ha) && !IS_QLAFX00(ha) && @@ -3775,13 +3775,13 @@ skip_msix: #else ret = pci_alloc_irq_vectors(ha->pdev, 1, 1, PCI_IRQ_MSI); #endif - if (!ret) { + if (ret > 0) { ql_dbg(ql_dbg_init, vha, 0x0038, "MSI: Enabled.\n"); ha->flags.msi_enabled = 1; } else ql_log(ql_log_warn, vha, 0x0039, - "Falling back-to INTa mode -- %d.\n", ret); + "Falling back-to INTa mode -- ret=%d.\n", ret); skip_msi: /* Skip INTx on ISP82xx. */ From 2806eeb93b3e9f84f8d3255c523a1868d1406846 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:28:14 +0000 Subject: [PATCH 27/57] qla2x00t-32gbit: Correctly retrieve and interpret active flash region ISP27XX/28XX supports multiple flash regions. This patch fixes issue where active flash region was not interpreted correctly during secure flash update process. Fixes: 5fa8774c7f38c ("scsi: qla2xxx: Add 28xx flash primary/secondary status/image mechanism") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191203223657.22109-2-hmadhani@marvell.com Signed-off-by: Michael Hernandez Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [mkp: typo] [ commit 4e71dcae0c4cd1e9d19b8b3d80214a4bcdca5a42 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8727 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_attr.c | 1 + qla2x00t-32gbit/qla_bsg.c | 2 +- qla2x00t-32gbit/qla_sup.c | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/qla2x00t-32gbit/qla_attr.c b/qla2x00t-32gbit/qla_attr.c index ae97e2f31..d7e7043f9 100644 --- a/qla2x00t-32gbit/qla_attr.c +++ b/qla2x00t-32gbit/qla_attr.c @@ -178,6 +178,7 @@ qla2x00_sysfs_read_nvram(struct file *filp, struct kobject *kobj, faddr = ha->flt_region_nvram; if (IS_QLA28XX(ha)) { + qla28xx_get_aux_images(vha, &active_regions); if (active_regions.aux.vpd_nvram == QLA27XX_SECONDARY_IMAGE) faddr = ha->flt_region_nvram_sec; } diff --git a/qla2x00t-32gbit/qla_bsg.c b/qla2x00t-32gbit/qla_bsg.c index b7b45ded8..b6af6cd7e 100644 --- a/qla2x00t-32gbit/qla_bsg.c +++ b/qla2x00t-32gbit/qla_bsg.c @@ -2559,7 +2559,7 @@ qla2x00_get_flash_image_status(struct bsg_job *bsg_job) struct qla_active_regions regions = { }; struct active_regions active_regions = { }; - qla28xx_get_aux_images(vha, &active_regions); + qla27xx_get_active_image(vha, &active_regions); regions.global_image = active_regions.global; if (IS_QLA28XX(ha)) { diff --git a/qla2x00t-32gbit/qla_sup.c b/qla2x00t-32gbit/qla_sup.c index f2d5115b2..b93a0d99e 100644 --- a/qla2x00t-32gbit/qla_sup.c +++ b/qla2x00t-32gbit/qla_sup.c @@ -847,15 +847,15 @@ qla2xxx_get_flt_info(scsi_qla_host_t *vha, uint32_t flt_addr) ha->flt_region_img_status_pri = start; break; case FLT_REG_IMG_SEC_27XX: - if (IS_QLA27XX(ha) && !IS_QLA28XX(ha)) + if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) ha->flt_region_img_status_sec = start; break; case FLT_REG_FW_SEC_27XX: - if (IS_QLA27XX(ha) && !IS_QLA28XX(ha)) + if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) ha->flt_region_fw_sec = start; break; case FLT_REG_BOOTLOAD_SEC_27XX: - if (IS_QLA27XX(ha) && !IS_QLA28XX(ha)) + if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) ha->flt_region_boot_sec = start; break; case FLT_REG_AUX_IMG_PRI_28XX: From 6c892b651df670bea10a1da93dd4dd07cee3cd95 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:28:38 +0000 Subject: [PATCH 28/57] qla2x00t-32gbit: Added support for MPI and PEP regions for ISP28XX This patch adds support for MPI/PEP region updates which is required with secure flash updates for ISP28XX. Fixes: 3f006ac342c0 ("scsi: qla2xxx: Secure flash update support for ISP28XX") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191203223657.22109-3-hmadhani@marvell.com Signed-off-by: Michael Hernandez Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit a530bf691f0e4691214562c165e6c8889dc51e57 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8728 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_fw.h | 4 ++++ qla2x00t-32gbit/qla_sup.c | 27 ++++++++++++++++++++++----- 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/qla2x00t-32gbit/qla_fw.h b/qla2x00t-32gbit/qla_fw.h index 3d9df80c4..2ea212e0e 100644 --- a/qla2x00t-32gbit/qla_fw.h +++ b/qla2x00t-32gbit/qla_fw.h @@ -1535,6 +1535,10 @@ struct qla_flt_header { #define FLT_REG_NVRAM_SEC_28XX_1 0x10F #define FLT_REG_NVRAM_SEC_28XX_2 0x111 #define FLT_REG_NVRAM_SEC_28XX_3 0x113 +#define FLT_REG_MPI_PRI_28XX 0xD3 +#define FLT_REG_MPI_SEC_28XX 0xF0 +#define FLT_REG_PEP_PRI_28XX 0xD1 +#define FLT_REG_PEP_SEC_28XX 0xF1 struct qla_flt_region { uint16_t code; diff --git a/qla2x00t-32gbit/qla_sup.c b/qla2x00t-32gbit/qla_sup.c index b93a0d99e..ae9d7422e 100644 --- a/qla2x00t-32gbit/qla_sup.c +++ b/qla2x00t-32gbit/qla_sup.c @@ -2725,8 +2725,11 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff, "Region %x is secure\n", region.code); - if (region.code == FLT_REG_FW || - region.code == FLT_REG_FW_SEC_27XX) { + switch (region.code) { + case FLT_REG_FW: + case FLT_REG_FW_SEC_27XX: + case FLT_REG_MPI_PRI_28XX: + case FLT_REG_MPI_SEC_28XX: fw_array = dwptr; /* 1st fw array */ @@ -2757,9 +2760,23 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, buf_size_without_sfub += risc_size; fw_array += risc_size; } - } else { - ql_log(ql_log_warn + ql_dbg_verbose, vha, 0xffff, - "Secure region %x not supported\n", + break; + + case FLT_REG_PEP_PRI_28XX: + case FLT_REG_PEP_SEC_28XX: + fw_array = dwptr; + + /* 1st fw array */ + risc_size = be32_to_cpu(fw_array[3]); + risc_attr = be32_to_cpu(fw_array[9]); + + buf_size_without_sfub = risc_size; + fw_array += risc_size; + break; + + default: + ql_log(ql_log_warn + ql_dbg_verbose, vha, + 0xffff, "Secure region %x not supported\n", region.code); rval = QLA_COMMAND_ERROR; goto done; From 686aa95dcf662b70d93112eaf82e3e7cee17c3c4 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:28:59 +0000 Subject: [PATCH 29/57] qla2x00t-32gbit: Fix incorrect SFUB length used for Secure Flash Update MB Cmd SFUB length should be in DWORDs when passed to FW. Fixes: 3f006ac342c03 ("scsi: qla2xxx: Secure flash update support for ISP28XX") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191203223657.22109-4-hmadhani@marvell.com Signed-off-by: Michael Hernandez Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit c868907e1ac6a08a17f8fa9ce482c0a496896e9e upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8729 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_sup.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_sup.c b/qla2x00t-32gbit/qla_sup.c index ae9d7422e..bbe90354f 100644 --- a/qla2x00t-32gbit/qla_sup.c +++ b/qla2x00t-32gbit/qla_sup.c @@ -2897,7 +2897,7 @@ qla28xx_write_flash_data(scsi_qla_host_t *vha, uint32_t *dwptr, uint32_t faddr, "Sending Secure Flash MB Cmd\n"); rval = qla28xx_secure_flash_update(vha, 0, region.code, buf_size_without_sfub, sfub_dma, - sizeof(struct secure_flash_update_block)); + sizeof(struct secure_flash_update_block) >> 2); if (rval != QLA_SUCCESS) { ql_log(ql_log_warn, vha, 0xffff, "Secure Flash MB Cmd failed %x.", rval); From 5bab3ecb99d7014e66dc4e1cd70d79e2293b2899 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:29:20 +0000 Subject: [PATCH 30/57] qla2x00t-32gbit: Use explicit LOGO in target mode Target makes implicit LOGO on session teardown. LOGO ELS is not send on the wire and initiator is not aware that target no longer wants talking to it. Initiator keeps sending I/O requests, target responds with BA_RJT, they time out and then initiator sends ABORT TASK (ABTS-LS). Current behaviour incurs unneeded I/O timeout and can be fixed for some initiators by making explicit LOGO on session deletion. Link: https://lore.kernel.org/r/20191125165702.1013-3-r.bolshakov@yadro.com Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen [ commit 86196a8fa8a84af1395a28ea0548f2ce6ae9bc22 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8730 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla2x00-target/scst_qla2xxx.c | 2 ++ qla2x00t-32gbit/qla_def.h | 1 + qla2x00t-32gbit/qla_iocb.c | 16 ++++++++++++---- qla2x00t-32gbit/qla_target.c | 1 + 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/qla2x00t-32gbit/qla2x00-target/scst_qla2xxx.c b/qla2x00t-32gbit/qla2x00-target/scst_qla2xxx.c index c65ea0f49..9347c294f 100644 --- a/qla2x00t-32gbit/qla2x00-target/scst_qla2xxx.c +++ b/qla2x00t-32gbit/qla2x00-target/scst_qla2xxx.c @@ -870,6 +870,8 @@ static int sqa_close_session(struct scst_session *scst_sess) unsigned long flags; struct qla_hw_data *ha = fcport->vha->hw; + fcport->explicit_logout = 1; + spin_lock_irqsave(&ha->tgt.sess_lock, flags); sqa_qla2xxx_put_sess(fcport); spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index 7d8630cee..b817847b7 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -2427,6 +2427,7 @@ typedef struct fc_port { unsigned int id_changed:1; unsigned int scan_needed:1; unsigned int n2n_flag:1; + unsigned int explicit_logout:1; struct completion nvme_del_done; uint32_t nvme_prli_service_param; diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index 07caa095a..54b5392f1 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -2411,11 +2411,19 @@ qla2x00_login_iocb(srb_t *sp, struct mbx_entry *mbx) static void qla24xx_logout_iocb(srb_t *sp, struct logio_entry_24xx *logio) { + u16 control_flags = LCF_COMMAND_LOGO; logio->entry_type = LOGINOUT_PORT_IOCB_TYPE; - logio->control_flags = - cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO); - if (!sp->fcport->keep_nport_handle) - logio->control_flags |= cpu_to_le16(LCF_FREE_NPORT); + + if (sp->fcport->explicit_logout) { + control_flags |= LCF_EXPL_LOGO|LCF_FREE_NPORT; + } else { + control_flags |= LCF_IMPL_LOGO; + + if (!sp->fcport->keep_nport_handle) + control_flags |= LCF_FREE_NPORT; + } + + logio->control_flags = cpu_to_le16(control_flags); logio->nport_handle = cpu_to_le16(sp->fcport->loop_id); logio->port_id[0] = sp->fcport->d_id.b.al_pa; logio->port_id[1] = sp->fcport->d_id.b.area; diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index 099c0de63..43e9191a4 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -1117,6 +1117,7 @@ void qlt_free_session_done(struct work_struct *work) } } + sess->explicit_logout = 0; spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); sess->free_pending = 0; From d0a1eb961207efd4819dca5e2dacf27b494d71c3 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:30:18 +0000 Subject: [PATCH 31/57] qla2x00t-32gbit: Initialize free_work before flushing it Target creation triggers a new BUG_ON introduced in in commit 4d43d395fed1 ("workqueue: Try to catch flush_work() without INIT_WORK()."). The BUG_ON reveals an attempt to flush free_work in qla24xx_do_nack_work before it's initialized in qlt_unreg_sess: WARNING: CPU: 7 PID: 211 at kernel/workqueue.c:3031 __flush_work.isra.38+0x40/0x2e0 CPU: 7 PID: 211 Comm: kworker/7:1 Kdump: loaded Tainted: G E 5.3.0-rc7-vanilla+ #2 Workqueue: qla2xxx_wq qla2x00_iocb_work_fn [qla2xxx] NIP [c000000000159620] __flush_work.isra.38+0x40/0x2e0 LR [c0080000009d91b0] qla24xx_do_nack_work+0x88/0x180 [qla2xxx] Call Trace: [c000000005f3f9c0] [c000000000159644] __flush_work.isra.38+0x64/0x2e0 (unreliable) [c000000005f3fa50] [c0080000009d91a0] qla24xx_do_nack_work+0x78/0x180 [qla2xxx] [c000000005f3fae0] [c0080000009496ec] qla2x00_do_work+0x604/0xb90 [qla2xxx] [c000000005f3fc40] [c008000000949cd8] qla2x00_iocb_work_fn+0x60/0xe0 [qla2xxx] [c000000005f3fc80] [c000000000157bb8] process_one_work+0x2c8/0x5b0 [c000000005f3fd10] [c000000000157f28] worker_thread+0x88/0x660 [c000000005f3fdb0] [c000000000161d64] kthread+0x1a4/0x1b0 [c000000005f3fe20] [c00000000000b960] ret_from_kernel_thread+0x5c/0x7c Fixes: 1021f0bc2f3d6 ("scsi: qla2xxx: allow session delete to finish before create.") Cc: Quinn Tran Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191125165702.1013-4-r.bolshakov@yadro.com Acked-by: Himanshu Madhani Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Reviewed-by: Bart Van Assche Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen [ commit 4c86b037a6db3ad2922ef3ba8a8989eb7794e040 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8731 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 1 + qla2x00t-32gbit/qla_target.c | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 6c28f38f8..b42be42ff 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -4852,6 +4852,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vha, gfp_t flags) } INIT_WORK(&fcport->del_work, qla24xx_delete_sess_fn); + INIT_WORK(&fcport->free_work, qlt_free_session_done); INIT_WORK(&fcport->reg_work, qla_register_fcport_fn); INIT_LIST_HEAD(&fcport->gnl_entry); INIT_LIST_HEAD(&fcport->list); diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index 43e9191a4..0593837ca 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -1399,7 +1399,6 @@ static struct fc_port *qlt_create_sess( } INIT_WORK(&sess->del_work, qla24xx_delete_sess_fn); - INIT_WORK(&sess->free_work, qlt_free_session_done); spin_lock_irqsave(&ha->tgt.sess_lock, flags); if (!IS_SW_RESV_ADDR(sess->d_id)) From 5c3f238b761e216b01166553dfe06db7901b380e Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:30:45 +0000 Subject: [PATCH 32/57] qla2x00t-32gbit: Drop superfluous INIT_WORK of del_work del_work is already initialized inside qla2x00_alloc_fcport, there's no need to overwrite it. Indeed, it might prevent complete traversal of workqueue list. Fixes: a01c77d2cbc45 ("scsi: qla2xxx: Move session delete to driver work queue") Cc: Quinn Tran Link: https://lore.kernel.org/r/20191125165702.1013-5-r.bolshakov@yadro.com Acked-by: Himanshu Madhani Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Reviewed-by: Bart Van Assche Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen [ commit 600954e6f2df695434887dfc6a99a098859990cf upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8732 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_target.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index 0593837ca..05b774a1b 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -1398,8 +1398,6 @@ static struct fc_port *qlt_create_sess( return NULL; } - INIT_WORK(&sess->del_work, qla24xx_delete_sess_fn); - spin_lock_irqsave(&ha->tgt.sess_lock, flags); if (!IS_SW_RESV_ADDR(sess->d_id)) vha->vha_tgt.qla_tgt->sess_count++; From cf596469d66df53987a84745b50675603c5c1c2a Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:31:06 +0000 Subject: [PATCH 33/57] qla2x00t-32gbit: Change discovery state before PLOGI When a port sends PLOGI, discovery state should be changed to login pending, otherwise RELOGIN_NEEDED bit is set in qla24xx_handle_plogi_done_event(). RELOGIN_NEEDED triggers another PLOGI, and it never goes out of the loop until login timer expires. Fixes: 8777e4314d397 ("scsi: qla2xxx: Migrate NVME N2N handling into state machine") Fixes: 8b5292bcfcacf ("scsi: qla2xxx: Fix Relogin to prevent modifying scan_state flag") Cc: Quinn Tran Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191125165702.1013-6-r.bolshakov@yadro.com Acked-by: Himanshu Madhani Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen [ commit 58e39a2ce4be08162c0368030cdc405f7fd849aa upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8733 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 1 + 1 file changed, 1 insertion(+) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index b42be42ff..fc2ff169d 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -533,6 +533,7 @@ static int qla_post_els_plogi_work(struct scsi_qla_host *vha, fc_port_t *fcport) e->u.fcport.fcport = fcport; fcport->flags |= FCF_ASYNC_ACTIVE; + fcport->disc_state = DSC_LOGIN_PEND; return qla2x00_post_work(vha, e); } From 63d90db75d97246f55a179b8ca2195f8515ecc40 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:31:26 +0000 Subject: [PATCH 34/57] qla2x00t-32gbit: Allow PLOGI in target mode According to FC-LS-3 (Fibre Channel Link Services) 6.3.2.4 "N_Port Login - No Fabric present", if both parties in the point-to-point connection know N_Port_Names of each other, Nx_Port with the highest N_Port_name shall transmit PLOGI. The specification sets no restrictions on the port role that should send PLOGI. However, FCP-4 (Fibre Channel Protocol for SCSI, Fourth Version) 6.2 "Overview of Process Login and Process Logout", instructs that in point-to-point topology, initiator shall send explicit PRLI ELS. The change fixes stuck P2P login, when target WWPN is higher than initiator WWPN. Cc: Quinn Tran Cc: Himanshu Madhani Link: https://lore.kernel.org/r/20191125165702.1013-7-r.bolshakov@yadro.com Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen [ commit a9ed06d4e640a8dc978a4649ab78dac8b16d2db6 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8734 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index fc2ff169d..d2c1f8080 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -1527,8 +1527,8 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport) } } - /* for pure Target Mode. Login will not be initiated */ - if (vha->host->active_mode == MODE_TARGET) + /* Target won't initiate port login if fabric is present */ + if (vha->host->active_mode == MODE_TARGET && !N2N_TOPO(vha->hw)) return 0; if (fcport->flags & FCF_ASYNC_SENT) { @@ -1720,6 +1720,10 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha, void qla_handle_els_plogi_done(scsi_qla_host_t *vha, struct event_arg *ea) { + /* for pure Target Mode, PRLI will not be initiated */ + if (vha->host->active_mode == MODE_TARGET) + return; + ql_dbg(ql_dbg_disc, vha, 0x2118, "%s %d %8phC post PRLI\n", __func__, __LINE__, ea->fcport->port_name); From b047e2a1695902a29418cb719b1496a075f4f81b Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:34:15 +0000 Subject: [PATCH 35/57] qla2x00t-32gbit: Don't call qlt_async_event twice MBA_PORT_UPDATE generates duplicate log lines in target mode because qlt_async_event is called twice. Drop the calls within the case as the function will be called right after the switch statement. Cc: Quinn Tran Link: https://lore.kernel.org/r/20191125165702.1013-8-r.bolshakov@yadro.com Acked-by: Himanshu Madhani Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Acked-by: Himanshu Madhani Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen [ commit 2c2f4bed9b6299e6430a65a29b5d27b8763fdf25 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8735 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_isr.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index 848216ca4..bb14de4ab 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -1073,8 +1073,6 @@ global_port_update: ql_dbg(ql_dbg_async, vha, 0x5011, "Asynchronous PORT UPDATE ignored %04x/%04x/%04x.\n", mb[1], mb[2], mb[3]); - - qlt_async_event(mb[0], vha, mb); break; } @@ -1091,8 +1089,6 @@ global_port_update: set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags); set_bit(VP_CONFIG_OK, &vha->vp_flags); - - qlt_async_event(mb[0], vha, mb); break; case MBA_RSCN_UPDATE: /* State Change Registration */ From 695f139aef4aadb0cdbd06536f33b13aff6fc5c4 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:34:42 +0000 Subject: [PATCH 36/57] qla2x00t-32gbit: Fix PLOGI payload and ELS IOCB dump length The size of the buffer is hardcoded as 0x70 or 112 bytes, while the size of ELS IOCB is 0x40 and the size of PLOGI payload returned by Get Parameters command is 0x74. Cc: Quinn Tran Link: https://lore.kernel.org/r/20191125165702.1013-9-r.bolshakov@yadro.com Acked-by: Himanshu Madhani Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen [ commit 0334cdea1fba36fad8bdf9516f267ce01de625f7 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8736 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_iocb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index 54b5392f1..f5cf2c381 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -2690,7 +2690,8 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x3073, "PLOGI ELS IOCB:\n"); ql_dump_buffer(ql_log_info, vha, 0x0109, - (uint8_t *)els_iocb, 0x70); + (uint8_t *)els_iocb, + sizeof(*els_iocb)); } else { els_iocb->control_flags = 1 << 13; els_iocb->tx_byte_count = @@ -2948,7 +2949,8 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode, ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x3073, "PLOGI buffer:\n"); ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x0109, - (uint8_t *)elsio->u.els_plogi.els_plogi_pyld, 0x70); + (uint8_t *)elsio->u.els_plogi.els_plogi_pyld, + sizeof(*elsio->u.els_plogi.els_plogi_pyld)); rval = qla2x00_start_sp(sp); if (rval != QLA_SUCCESS) { From 0a6f0f9ac53b3f150932dffebc126342616a830c Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:35:02 +0000 Subject: [PATCH 37/57] qla2x00t-32gbit: Configure local loop for N2N target qla2x00_configure_local_loop initializes PLOGI payload for PLOGI ELS using Get Parameters mailbox command. In the case when the driver is running in target mode, the topology is N2N and the target port has higher WWPN, LOCAL_LOOP_UPDATE bit is cleared too early and PLOGI payload is not initialized by the Get Parameters command. That causes a failure of ELS IOCB carrying the PLOGI with 0x15 aka Data Underrun error. LOCAL_LOOP_UPDATE has to be set to initialize PLOGI payload. Fixes: 48acad099074 ("scsi: qla2xxx: Fix N2N link re-connect") Link: https://lore.kernel.org/r/20191125165702.1013-10-r.bolshakov@yadro.com Acked-by: Quinn Tran Acked-by: Himanshu Madhani Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen [ commit fd1de5830a5abaf444cc4312871e02c41e24fdc1 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8737 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index d2c1f8080..c893d89ed 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -4936,14 +4936,8 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) set_bit(RSCN_UPDATE, &flags); clear_bit(LOCAL_LOOP_UPDATE, &flags); - } else if (ha->current_topology == ISP_CFG_N) { - clear_bit(RSCN_UPDATE, &flags); - if (qla_tgt_mode_enabled(vha)) { - /* allow the other side to start the login */ - clear_bit(LOCAL_LOOP_UPDATE, &flags); - set_bit(RELOGIN_NEEDED, &vha->dpc_flags); - } - } else if (ha->current_topology == ISP_CFG_NL) { + } else if (ha->current_topology == ISP_CFG_NL || + ha->current_topology == ISP_CFG_N) { clear_bit(RSCN_UPDATE, &flags); set_bit(LOCAL_LOOP_UPDATE, &flags); } else if (!vha->flags.online || From 341ef8cf2c1412e8a757aba4ed3607694e5f3b49 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:35:23 +0000 Subject: [PATCH 38/57] qla2x00t-32gbit: Send Notify ACK after N2N PLOGI qlt_handle_login schedules session for deletion even if a login is in progress. That causes login bouncing, i.e. a few logins are made before it settles down. Complete the first login by sending Notify Acknowledge IOCB via qlt_plogi_ack_unref if the session is pending login completion. Fixes: 9cd883f07a54 ("scsi: qla2xxx: Fix session cleanup for N2N") Cc: Krishna Kant Cc: Alexei Potashnik Link: https://lore.kernel.org/r/20191125165702.1013-11-r.bolshakov@yadro.com Acked-by: Quinn Tran Acked-by: Himanshu Madhani Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen [ commit 5e6b01d84b9d20bcd77fc7c4733a2a4149bf220a upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8738 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_target.c | 1 + 1 file changed, 1 insertion(+) diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index 05b774a1b..2538530fa 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -4863,6 +4863,7 @@ static int qlt_handle_login(struct scsi_qla_host *vha, switch (sess->disc_state) { case DSC_DELETED: + case DSC_LOGIN_PEND: qlt_plogi_ack_unref(vha, pla); break; From 027599ccd00fed67900807f502f03b13d391af94 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:35:42 +0000 Subject: [PATCH 39/57] qla2x00t-32gbit: Don't defer relogin unconditonally qla2x00_configure_local_loop sets RELOGIN_NEEDED bit and calls qla24xx_fcport_handle_login to perform the login. This bit triggers a wake up of DPC later after a successful login. The deferred call is not needed if login succeeds, and it's set in qla24xx_fcport_handle_login in case of errors, hence it should be safe to drop. Link: https://lore.kernel.org/r/20191125165702.1013-12-r.bolshakov@yadro.com Acked-by: Himanshu Madhani Acked-by: Quinn Tran Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen [ commit dabc5ec915f3a2c657ecfb529cd3d4ec303a4412 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8739 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 1 - 1 file changed, 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index c893d89ed..aa5204163 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -5054,7 +5054,6 @@ qla2x00_configure_local_loop(scsi_qla_host_t *vha) memcpy(&ha->plogi_els_payld.data, (void *)ha->init_cb, sizeof(ha->plogi_els_payld.data)); - set_bit(RELOGIN_NEEDED, &vha->dpc_flags); } else { ql_dbg(ql_dbg_init, vha, 0x00d1, "PLOGI ELS param read fail.\n"); From be35a0b6159969a4c4165a006d830da506697fa2 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:36:11 +0000 Subject: [PATCH 40/57] qla2x00t-32gbit: Ignore PORT UPDATE after N2N PLOGI PORT UPDATE asynchronous event is generated on the host that issues PLOGI ELS (in the case of higher WWPN). In that case, the event shouldn't be handled as it sets unwanted DPC flags (i.e. LOOP_RESYNC_NEEDED) that trigger link flap. Ignore the event if the host has higher WWPN, but handle otherwise. Cc: Quinn Tran Link: https://lore.kernel.org/r/20191125165702.1013-13-r.bolshakov@yadro.com Acked-by: Himanshu Madhani Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen [ commit af22f0c7b052c5c203207f1e5ebd6aa65f87c538 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8740 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_mbx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_mbx.c b/qla2x00t-32gbit/qla_mbx.c index 0cf94f05f..b7c1108c4 100644 --- a/qla2x00t-32gbit/qla_mbx.c +++ b/qla2x00t-32gbit/qla_mbx.c @@ -3921,6 +3921,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, vha->d_id.b24 = 0; vha->d_id.b.al_pa = 1; ha->flags.n2n_bigger = 1; + ha->flags.n2n_ae = 0; id.b.al_pa = 2; ql_dbg(ql_dbg_async, vha, 0x5075, @@ -3931,6 +3932,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, "Format 1: Remote login - Waiting for WWPN %8phC.\n", rptid_entry->u.f1.port_name); ha->flags.n2n_bigger = 0; + ha->flags.n2n_ae = 1; } qla24xx_post_newsess_work(vha, &id, rptid_entry->u.f1.port_name, @@ -3942,7 +3944,6 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha, /* if our portname is higher then initiate N2N login */ set_bit(N2N_LOGIN_NEEDED, &vha->dpc_flags); - ha->flags.n2n_ae = 1; return; break; case TOPO_FL: From bb6f896ac4c51fb53bbc73a0515a875dc9f49c01 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:36:30 +0000 Subject: [PATCH 41/57] qla2x00t-32gbit: Add debug dump of LOGO payload and ELS IOCB The change adds a way to debug LOGO ELS, likewise PLOGI. Link: https://lore.kernel.org/r/20191125165702.1013-14-r.bolshakov@yadro.com Acked-by: Himanshu Madhani Acked-by: Quinn Tran Reviewed-by: Hannes Reinecke Tested-by: Hannes Reinecke Reviewed-by: Bart Van Assche Signed-off-by: Roman Bolshakov Signed-off-by: Martin K. Petersen [ commit 9545767db3cde2d4f9ca581d096d97ed00754282 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8741 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_iocb.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index f5cf2c381..81ce7c026 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -2631,6 +2631,10 @@ qla24xx_els_dcmd_iocb(scsi_qla_host_t *vha, int els_opcode, memcpy(elsio->u.els_logo.els_logo_pyld, &logo_pyld, sizeof(struct els_logo_payload)); + ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x3075, "LOGO buffer:"); + ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x010a, + elsio->u.els_logo.els_logo_pyld, + sizeof(*elsio->u.els_logo.els_logo_pyld)); rval = qla2x00_start_sp(sp); if (rval != QLA_SUCCESS) { @@ -2703,6 +2707,11 @@ qla24xx_els_logo_iocb(srb_t *sp, struct els_entry_24xx *els_iocb) els_iocb->rx_byte_count = 0; els_iocb->rx_address = 0; els_iocb->rx_len = 0; + ql_dbg(ql_dbg_io + ql_dbg_buffer, vha, 0x3076, + "LOGO ELS IOCB:"); + ql_dump_buffer(ql_log_info, vha, 0x010b, + els_iocb, + sizeof(*els_iocb)); } sp->vha->qla_stats.control_requests++; From c27e7694d80d7c8b6c2893171bba3556454f4fac Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:36:52 +0000 Subject: [PATCH 42/57] qla2x00t-32gbit: Remove defer flag to indicate immeadiate port loss During cable pull test case, if the port is disconnected for time larger than devloss timeout, driver does not mark path offline. In such case, instead of notifying SCSI-ML of loop down, driver goes into endless loop of device relogin because defer flag is set. With newer handling of device relogin in driver discovery, defer flag is now redundant. This patch removes defer flag and cleans up code handling port lost indication to SCSI-ML. Link: https://lore.kernel.org/r/20191217220617.28084-2-hmadhani@marvell.com Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit 3c75ad1d87c7d277c6174051b98757fe981d592d upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8742 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_gbl.h | 4 +-- qla2x00t-32gbit/qla_init.c | 18 ++++++------ qla2x00t-32gbit/qla_isr.c | 16 +++++----- qla2x00t-32gbit/qla_mid.c | 6 ++-- qla2x00t-32gbit/qla_mr.c | 10 +++---- qla2x00t-32gbit/qla_nx.c | 2 +- qla2x00t-32gbit/qla_os.c | 57 +++++++++++------------------------- qla2x00t-32gbit/qla_target.c | 2 +- 8 files changed, 45 insertions(+), 70 deletions(-) diff --git a/qla2x00t-32gbit/qla_gbl.h b/qla2x00t-32gbit/qla_gbl.h index afc0bb6b6..0fdc5f93a 100644 --- a/qla2x00t-32gbit/qla_gbl.h +++ b/qla2x00t-32gbit/qla_gbl.h @@ -257,8 +257,8 @@ extern scsi_qla_host_t *qla24xx_create_vhost(struct fc_vport *); extern void qla2x00_sp_free_dma(srb_t *sp); extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *); -extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int); -extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int); +extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int); +extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *); extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *); diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index aa5204163..c689e34a5 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -425,7 +425,7 @@ qla2x00_async_prlo_done(struct scsi_qla_host *vha, fc_port_t *fcport, fcport->flags &= ~FCF_ASYNC_ACTIVE; /* Don't re-login in target mode */ if (!fcport->tgt_session) - qla2x00_mark_device_lost(vha, fcport, 1, 0); + qla2x00_mark_device_lost(vha, fcport, 1); qlt_logo_completion_handler(fcport, data[0]); } @@ -2000,7 +2000,7 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) if (ea->data[1] & QLA_LOGIO_LOGIN_RETRIED) set_bit(RELOGIN_NEEDED, &vha->dpc_flags); else - qla2x00_mark_device_lost(vha, ea->fcport, 1, 0); + qla2x00_mark_device_lost(vha, ea->fcport, 1); break; case MBS_LOOP_ID_USED: /* data[1] = IO PARAM 1 = nport ID */ @@ -5230,7 +5230,7 @@ skip_login: qla_ini_mode_enabled(vha)) && atomic_read(&fcport->state) == FCS_ONLINE) { qla2x00_mark_device_lost(vha, fcport, - ql2xplogiabsentdevice, 0); + ql2xplogiabsentdevice); if (fcport->loop_id != FC_NO_LOOP_ID && (fcport->flags & FCF_FCP2_DEVICE) == 0 && fcport->port_type != FCT_INITIATOR && @@ -5905,7 +5905,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) qla_ini_mode_enabled(vha)) && atomic_read(&fcport->state) == FCS_ONLINE) { qla2x00_mark_device_lost(vha, fcport, - ql2xplogiabsentdevice, 0); + ql2xplogiabsentdevice); if (fcport->loop_id != FC_NO_LOOP_ID && (fcport->flags & FCF_FCP2_DEVICE) == 0 && fcport->port_type != FCT_INITIATOR && @@ -6071,7 +6071,7 @@ qla2x00_fabric_login(scsi_qla_host_t *vha, fc_port_t *fcport, ha->isp_ops->fabric_logout(vha, fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa); - qla2x00_mark_device_lost(vha, fcport, 1, 0); + qla2x00_mark_device_lost(vha, fcport, 1); rval = 1; break; @@ -6585,9 +6585,9 @@ qla2x00_quiesce_io(scsi_qla_host_t *vha) atomic_set(&ha->loop_down_timer, LOOP_DOWN_TIME); if (atomic_read(&vha->loop_state) != LOOP_DOWN) { atomic_set(&vha->loop_state, LOOP_DOWN); - qla2x00_mark_all_devices_lost(vha, 0); + qla2x00_mark_all_devices_lost(vha); list_for_each_entry(vp, &ha->vp_list, list) - qla2x00_mark_all_devices_lost(vp, 0); + qla2x00_mark_all_devices_lost(vp); } else { if (!atomic_read(&vha->loop_down_timer)) atomic_set(&vha->loop_down_timer, @@ -6663,14 +6663,14 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha) atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); if (atomic_read(&vha->loop_state) != LOOP_DOWN) { atomic_set(&vha->loop_state, LOOP_DOWN); - qla2x00_mark_all_devices_lost(vha, 0); + qla2x00_mark_all_devices_lost(vha); spin_lock_irqsave(&ha->vport_slock, flags); list_for_each_entry(vp, &ha->vp_list, list) { atomic_inc(&vp->vref_count); spin_unlock_irqrestore(&ha->vport_slock, flags); - qla2x00_mark_all_devices_lost(vp, 0); + qla2x00_mark_all_devices_lost(vp); spin_lock_irqsave(&ha->vport_slock, flags); atomic_dec(&vp->vref_count); diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index bb14de4ab..b42cf0bbc 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -800,7 +800,7 @@ skip_rio: if (atomic_read(&vha->loop_state) != LOOP_DOWN) { atomic_set(&vha->loop_state, LOOP_DOWN); atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); - qla2x00_mark_all_devices_lost(vha, 1); + qla2x00_mark_all_devices_lost(vha); } if (vha->vp_idx) { @@ -873,7 +873,7 @@ skip_rio: } vha->device_flags |= DFLG_NO_CABLE; - qla2x00_mark_all_devices_lost(vha, 1); + qla2x00_mark_all_devices_lost(vha); } if (vha->vp_idx) { @@ -893,7 +893,7 @@ skip_rio: if (atomic_read(&vha->loop_state) != LOOP_DOWN) { atomic_set(&vha->loop_state, LOOP_DOWN); atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); - qla2x00_mark_all_devices_lost(vha, 1); + qla2x00_mark_all_devices_lost(vha); } if (vha->vp_idx) { @@ -936,7 +936,7 @@ skip_rio: atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); if (!N2N_TOPO(ha)) - qla2x00_mark_all_devices_lost(vha, 1); + qla2x00_mark_all_devices_lost(vha); } if (vha->vp_idx) { @@ -965,7 +965,7 @@ skip_rio: if (!atomic_read(&vha->loop_down_timer)) atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); - qla2x00_mark_all_devices_lost(vha, 1); + qla2x00_mark_all_devices_lost(vha); } if (vha->vp_idx) { @@ -1034,7 +1034,6 @@ skip_rio: "Marking port lost loopid=%04x portid=%06x.\n", fcport->loop_id, fcport->d_id.b24); if (qla_ini_mode_enabled(vha)) { - qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1); fcport->logout_on_delete = 0; qlt_schedule_sess_for_deletion(fcport); } @@ -1046,14 +1045,14 @@ global_port_update: atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); vha->device_flags |= DFLG_NO_CABLE; - qla2x00_mark_all_devices_lost(vha, 1); + qla2x00_mark_all_devices_lost(vha); } if (vha->vp_idx) { atomic_set(&vha->vp_state, VP_FAILED); fc_vport_set_state(vha->fc_vport, FC_VPORT_FAILED); - qla2x00_mark_all_devices_lost(vha, 1); + qla2x00_mark_all_devices_lost(vha); } vha->flags.management_server_logged_in = 0; @@ -2769,7 +2768,6 @@ check_scsi_status: port_state_str[FCS_ONLINE], comp_status); - qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1); qlt_schedule_sess_for_deletion(fcport); } diff --git a/qla2x00t-32gbit/qla_mid.c b/qla2x00t-32gbit/qla_mid.c index eabc51271..8ae639d08 100644 --- a/qla2x00t-32gbit/qla_mid.c +++ b/qla2x00t-32gbit/qla_mid.c @@ -147,7 +147,7 @@ qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha) "Marking port dead, loop_id=0x%04x : %x.\n", fcport->loop_id, fcport->vha->vp_idx); - qla2x00_mark_device_lost(vha, fcport, 0, 0); + qla2x00_mark_device_lost(vha, fcport, 0); qla2x00_set_fcport_state(fcport, FCS_UNCONFIGURED); } } @@ -167,7 +167,7 @@ qla24xx_disable_vp(scsi_qla_host_t *vha) list_for_each_entry(fcport, &vha->vp_fcports, list) fcport->logout_on_delete = 0; - qla2x00_mark_all_devices_lost(vha, 0); + qla2x00_mark_all_devices_lost(vha); /* Remove port id from vp target map */ spin_lock_irqsave(&vha->hw->hardware_lock, flags); @@ -327,7 +327,7 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *vha) */ if (atomic_read(&vha->loop_state) != LOOP_DOWN) { atomic_set(&vha->loop_state, LOOP_DOWN); - qla2x00_mark_all_devices_lost(vha, 0); + qla2x00_mark_all_devices_lost(vha); } else { if (!atomic_read(&vha->loop_down_timer)) atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); diff --git a/qla2x00t-32gbit/qla_mr.c b/qla2x00t-32gbit/qla_mr.c index 4a9d3149f..116d586d8 100644 --- a/qla2x00t-32gbit/qla_mr.c +++ b/qla2x00t-32gbit/qla_mr.c @@ -1210,7 +1210,7 @@ qlafx00_find_all_targets(scsi_qla_host_t *vha, " Existing TGT-ID %x did not get " " offline event from firmware.\n", fcport->old_tgt_id); - qla2x00_mark_device_lost(vha, fcport, 0, 0); + qla2x00_mark_device_lost(vha, fcport, 0); set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); kfree(new_fcport); return rval; @@ -1274,7 +1274,7 @@ qlafx00_configure_all_targets(scsi_qla_host_t *vha) if (atomic_read(&fcport->state) == FCS_DEVICE_LOST) { if (fcport->port_type != FCT_INITIATOR) - qla2x00_mark_device_lost(vha, fcport, 0, 0); + qla2x00_mark_device_lost(vha, fcport, 0); } } @@ -1706,7 +1706,7 @@ qlafx00_tgt_detach(struct scsi_qla_host *vha, int tgt_id) if (!fcport) return; - qla2x00_mark_device_lost(vha, fcport, 0, 0); + qla2x00_mark_device_lost(vha, fcport, 0); return; } @@ -1740,7 +1740,7 @@ qlafx00_process_aen(struct scsi_qla_host *vha, struct qla_work_evt *evt) set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); } else if (evt->u.aenfx.mbx[2] == 2) { vha->device_flags |= DFLG_NO_CABLE; - qla2x00_mark_all_devices_lost(vha, 1); + qla2x00_mark_all_devices_lost(vha); } } break; @@ -2528,7 +2528,7 @@ check_scsi_status: atomic_read(&fcport->state)); if (atomic_read(&fcport->state) == FCS_ONLINE) - qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1); + qla2x00_mark_device_lost(fcport->vha, fcport, 1); break; case CS_ABORTED: diff --git a/qla2x00t-32gbit/qla_nx.c b/qla2x00t-32gbit/qla_nx.c index 8e360fd08..c04f401a7 100644 --- a/qla2x00t-32gbit/qla_nx.c +++ b/qla2x00t-32gbit/qla_nx.c @@ -3029,7 +3029,7 @@ qla8xxx_dev_failed_handler(scsi_qla_host_t *vha) /* Set DEV_FAILED flag to disable timer */ vha->device_flags |= DFLG_DEV_FAILED; qla2x00_abort_all_cmds(vha, DID_NO_CONNECT << 16); - qla2x00_mark_all_devices_lost(vha, 0); + qla2x00_mark_all_devices_lost(vha); vha->flags.online = 0; vha->flags.init_done = 0; } diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 5368f95ab..4188e5436 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -1147,7 +1147,7 @@ qla2x00_wait_for_sess_deletion(scsi_qla_host_t *vha) { u8 i; - qla2x00_mark_all_devices_lost(vha, 0); + qla2x00_mark_all_devices_lost(vha); for (i = 0; i < 10; i++) { if (wait_event_timeout(vha->fcport_waitQ, @@ -1704,7 +1704,7 @@ qla2x00_loop_reset(scsi_qla_host_t *vha) if (ha->flags.enable_lip_full_login && !IS_CNA_CAPABLE(ha)) { atomic_set(&vha->loop_state, LOOP_DOWN); atomic_set(&vha->loop_down_timer, LOOP_DOWN_TIME); - qla2x00_mark_all_devices_lost(vha, 0); + qla2x00_mark_all_devices_lost(vha); ret = qla2x00_full_login_lip(vha); if (ret != QLA_SUCCESS) { ql_dbg(ql_dbg_taskm, vha, 0x802d, @@ -3897,37 +3897,21 @@ void qla2x00_free_fcports(struct scsi_qla_host *vha) } static inline void -qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport, - int defer) +qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport) { - struct fc_rport *rport; - scsi_qla_host_t *base_vha; - unsigned long flags; + int now; if (!fcport->rport) return; - rport = fcport->rport; - if (defer) { - base_vha = pci_get_drvdata(vha->hw->pdev); - spin_lock_irqsave(vha->host->host_lock, flags); - fcport->drport = rport; - spin_unlock_irqrestore(vha->host->host_lock, flags); - qlt_do_generation_tick(vha, &base_vha->total_fcport_update_gen); - set_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags); - qla2xxx_wake_dpc(base_vha); - } else { - int now; - - if (rport) { - ql_dbg(ql_dbg_disc, fcport->vha, 0x2109, - "%s %8phN. rport %p roles %x\n", - __func__, fcport->port_name, rport, - rport->roles); - fc_remote_port_delete(rport); - } - qlt_do_generation_tick(vha, &now); + if (fcport->rport) { + ql_dbg(ql_dbg_disc, fcport->vha, 0x2109, + "%s %8phN. rport %p roles %x\n", + __func__, fcport->port_name, fcport->rport, + fcport->rport->roles); + fc_remote_port_delete(fcport->rport); } + qlt_do_generation_tick(vha, &now); } /* @@ -3940,18 +3924,18 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport, * Context: */ void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport, - int do_login, int defer) + int do_login) { if (IS_QLAFX00(vha->hw)) { qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST); - qla2x00_schedule_rport_del(vha, fcport, defer); + qla2x00_schedule_rport_del(vha, fcport); return; } if (atomic_read(&fcport->state) == FCS_ONLINE && vha->vp_idx == fcport->vha->vp_idx) { qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST); - qla2x00_schedule_rport_del(vha, fcport, defer); + qla2x00_schedule_rport_del(vha, fcport); } /* * We may need to retry the login, so don't change the state of the @@ -3980,7 +3964,7 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport, * Context: */ void -qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer) +qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha) { fc_port_t *fcport; @@ -4000,13 +3984,6 @@ qla2x00_mark_all_devices_lost(scsi_qla_host_t *vha, int defer) */ if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD) continue; - if (atomic_read(&fcport->state) == FCS_ONLINE) { - qla2x00_set_fcport_state(fcport, FCS_DEVICE_LOST); - if (defer) - qla2x00_schedule_rport_del(vha, fcport, defer); - else if (vha->vp_idx == fcport->vha->vp_idx) - qla2x00_schedule_rport_del(vha, fcport, defer); - } } } @@ -6946,13 +6923,13 @@ static void qla_pci_error_cleanup(scsi_qla_host_t *vha) qpair->online = 0; mutex_unlock(&ha->mq_lock); - qla2x00_mark_all_devices_lost(vha, 0); + qla2x00_mark_all_devices_lost(vha); spin_lock_irqsave(&ha->vport_slock, flags); list_for_each_entry(vp, &ha->vp_list, list) { atomic_inc(&vp->vref_count); spin_unlock_irqrestore(&ha->vport_slock, flags); - qla2x00_mark_all_devices_lost(vp, 0); + qla2x00_mark_all_devices_lost(vp); spin_lock_irqsave(&ha->vport_slock, flags); atomic_dec(&vp->vref_count); } diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index 2538530fa..fba835e4e 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -979,7 +979,7 @@ void qlt_free_session_done(struct work_struct *work) sess->send_els_logo); if (!IS_SW_RESV_ADDR(sess->d_id)) { - qla2x00_mark_device_lost(vha, sess, 0, 0); + qla2x00_mark_device_lost(vha, sess, 0); if (sess->send_els_logo) { qlt_port_logo_t logo; From 6ce21edf8babad144770526a2ddde6cc2e0b0f24 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:37:12 +0000 Subject: [PATCH 43/57] qla2x00t-32gbit: Fix fabric scan hang On timeout, SRB pointer was cleared from outstanding command array and dropped. It was not allowed to go through the done process and cleanup. This patch will abort the SRB where FW will return it with an error status and resume the normal cleanup. Link: https://lore.kernel.org/r/20191217220617.28084-3-hmadhani@marvell.com Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit f57a0107359605b29f4ea9afb8ee2e03473b1448 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8743 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_gbl.h | 1 + qla2x00t-32gbit/qla_init.c | 34 +++++++++++++++++-------------- qla2x00t-32gbit/qla_iocb.c | 41 ++++++++++++++++++++++++++++++-------- 3 files changed, 53 insertions(+), 23 deletions(-) diff --git a/qla2x00t-32gbit/qla_gbl.h b/qla2x00t-32gbit/qla_gbl.h index 0fdc5f93a..e60a834a5 100644 --- a/qla2x00t-32gbit/qla_gbl.h +++ b/qla2x00t-32gbit/qla_gbl.h @@ -259,6 +259,7 @@ extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *); extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int); extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *); +extern int qla24xx_async_abort_cmd(srb_t *, bool); extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *); diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index c689e34a5..0758b1cef 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -49,16 +49,9 @@ qla2x00_sp_timeout(struct timer_list *t) { srb_t *sp = from_timer(sp, t, u.iocb_cmd.timer); struct srb_iocb *iocb; - struct req_que *req; - unsigned long flags; - struct qla_hw_data *ha = sp->vha->hw; - WARN_ON_ONCE(irqs_disabled()); - spin_lock_irqsave(&ha->hardware_lock, flags); - req = sp->qpair->req; - req->outstanding_cmds[sp->handle] = NULL; + WARN_ON(irqs_disabled()); iocb = &sp->u.iocb_cmd; - spin_unlock_irqrestore(&ha->hardware_lock, flags); iocb->timeout(sp); } @@ -142,7 +135,7 @@ static void qla24xx_abort_sp_done(srb_t *sp, int res) sp->free(sp); } -static int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait) +int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait) { scsi_qla_host_t *vha = cmd_sp->vha; struct srb_iocb *abt_iocb; @@ -242,6 +235,7 @@ qla2x00_async_iocb_timeout(void *data) case SRB_NACK_PRLI: case SRB_NACK_LOGO: case SRB_CTRL_VP: + default: rc = qla24xx_async_abort_cmd(sp, false); if (rc) { spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags); @@ -258,10 +252,6 @@ qla2x00_async_iocb_timeout(void *data) sp->done(sp, QLA_FUNCTION_TIMEOUT); } break; - default: - WARN_ON_ONCE(true); - sp->done(sp, QLA_FUNCTION_TIMEOUT); - break; } } @@ -1758,9 +1748,23 @@ qla2x00_tmf_iocb_timeout(void *data) { srb_t *sp = data; struct srb_iocb *tmf = &sp->u.iocb_cmd; + int rc, h; + unsigned long flags; - tmf->u.tmf.comp_status = CS_TIMEOUT; - complete(&tmf->u.tmf.comp); + rc = qla24xx_async_abort_cmd(sp, false); + if (rc) { + spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags); + for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) { + if (sp->qpair->req->outstanding_cmds[h] == sp) { + sp->qpair->req->outstanding_cmds[h] = NULL; + break; + } + } + spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags); + tmf->u.tmf.comp_status = CS_TIMEOUT; + tmf->u.tmf.data = QLA_FUNCTION_FAILED; + complete(&tmf->u.tmf.comp); + } } static void qla2x00_tmf_sp_done(srb_t *sp, int res) diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index 81ce7c026..c202c34ef 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -2543,13 +2543,32 @@ qla2x00_els_dcmd_iocb_timeout(void *data) fc_port_t *fcport = sp->fcport; struct scsi_qla_host *vha = sp->vha; struct srb_iocb *lio = &sp->u.iocb_cmd; + unsigned long flags = 0; + int res, h; ql_dbg(ql_dbg_io, vha, 0x3069, "%s Timeout, hdl=%x, portid=%02x%02x%02x\n", sp->name, sp->handle, fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa); - complete(&lio->u.els_logo.comp); + /* Abort the exchange */ + res = qla24xx_async_abort_cmd(sp, false); + if (res) { + ql_dbg(ql_dbg_io, vha, 0x3070, + "mbx abort_command failed.\n"); + spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags); + for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) { + if (sp->qpair->req->outstanding_cmds[h] == sp) { + sp->qpair->req->outstanding_cmds[h] = NULL; + break; + } + } + spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags); + complete(&lio->u.els_logo.comp); + } else { + ql_dbg(ql_dbg_io, vha, 0x3071, + "mbx abort_command success.\n"); + } } static void qla2x00_els_dcmd_sp_done(srb_t *sp, int res) @@ -2723,23 +2742,29 @@ qla2x00_els_dcmd2_iocb_timeout(void *data) srb_t *sp = data; fc_port_t *fcport = sp->fcport; struct scsi_qla_host *vha = sp->vha; - struct qla_hw_data *ha = vha->hw; unsigned long flags = 0; - int res; + int res, h; ql_dbg(ql_dbg_io + ql_dbg_disc, vha, 0x3069, "%s hdl=%x ELS Timeout, %8phC portid=%06x\n", sp->name, sp->handle, fcport->port_name, fcport->d_id.b24); /* Abort the exchange */ - spin_lock_irqsave(&ha->hardware_lock, flags); - res = ha->isp_ops->abort_command(sp); + res = qla24xx_async_abort_cmd(sp, false); ql_dbg(ql_dbg_io, vha, 0x3070, "mbx abort_command %s\n", (res == QLA_SUCCESS) ? "successful" : "failed"); - spin_unlock_irqrestore(&ha->hardware_lock, flags); - - sp->done(sp, QLA_FUNCTION_TIMEOUT); + if (res) { + spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags); + for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) { + if (sp->qpair->req->outstanding_cmds[h] == sp) { + sp->qpair->req->outstanding_cmds[h] = NULL; + break; + } + } + spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags); + sp->done(sp, QLA_FUNCTION_TIMEOUT); + } } void qla2x00_els_dcmd2_free(scsi_qla_host_t *vha, struct els_plogi *els_plogi) From d847f2552492b88ffeadaaa58f2167e00d46617c Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:37:40 +0000 Subject: [PATCH 44/57] qla2x00t-32gbit: Add a shadow variable to hold disc_state history of fcport This patch adds a shadow variable to hold disc_state history for the fcport and prints state transition when the logging is enabled. Link: https://lore.kernel.org/r/20191217220617.28084-4-hmadhani@marvell.com Signed-off-by: Shyam Sundar Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit 27258a5771446f9c7edc929ecb76fe2c12c29d97 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8744 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_dbg.c | 2 +- qla2x00t-32gbit/qla_def.h | 14 ++++++++++++++ qla2x00t-32gbit/qla_gbl.h | 1 + qla2x00t-32gbit/qla_gs.c | 2 +- qla2x00t-32gbit/qla_init.c | 29 +++++++++++++++-------------- qla2x00t-32gbit/qla_inline.h | 24 ++++++++++++++++++++++++ qla2x00t-32gbit/qla_iocb.c | 7 ++++--- qla2x00t-32gbit/qla_os.c | 2 +- qla2x00t-32gbit/qla_target.c | 11 ++++++----- 9 files changed, 67 insertions(+), 25 deletions(-) diff --git a/qla2x00t-32gbit/qla_dbg.c b/qla2x00t-32gbit/qla_dbg.c index 30afc59c1..e5500bba0 100644 --- a/qla2x00t-32gbit/qla_dbg.c +++ b/qla2x00t-32gbit/qla_dbg.c @@ -18,7 +18,7 @@ * | Device Discovery | 0x2134 | 0x210e-0x2116 | * | | | 0x211a | * | | | 0x211c-0x2128 | - * | | | 0x212a-0x2130 | + * | | | 0x212a-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 b817847b7..d2d56df65 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -2491,6 +2491,7 @@ typedef struct fc_port { struct qla_tgt_sess *tgt_session; struct ct_sns_desc ct_desc; enum discovery_state disc_state; + atomic_t shadow_disc_state; enum discovery_state next_disc_state; enum login_state fw_login_state; unsigned long dm_login_expire; @@ -2537,6 +2538,19 @@ struct event_arg { extern const char *const port_state_str[5]; +static const char * const port_dstate_str[] = { + "DELETED", + "GNN_ID", + "GNL", + "LOGIN_PEND", + "LOGIN_FAILED", + "GPDB", + "UPD_FCPORT", + "LOGIN_COMPLETE", + "ADISC", + "DELETE_PEND" +}; + /* * FC port flags. */ diff --git a/qla2x00t-32gbit/qla_gbl.h b/qla2x00t-32gbit/qla_gbl.h index e60a834a5..06ce1c5af 100644 --- a/qla2x00t-32gbit/qla_gbl.h +++ b/qla2x00t-32gbit/qla_gbl.h @@ -80,6 +80,7 @@ extern int qla24xx_async_gnl(struct scsi_qla_host *, fc_port_t *); int qla2x00_post_work(struct scsi_qla_host *vha, struct qla_work_evt *e); extern void *qla2x00_alloc_iocbs_ready(struct qla_qpair *, srb_t *); extern int qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *, fc_port_t *); +extern int qla24xx_async_abort_cmd(srb_t *, bool); extern void qla2x00_set_fcport_state(fc_port_t *fcport, int state); extern fc_port_t * diff --git a/qla2x00t-32gbit/qla_gs.c b/qla2x00t-32gbit/qla_gs.c index 446a9d6ba..f11fb00bf 100644 --- a/qla2x00t-32gbit/qla_gs.c +++ b/qla2x00t-32gbit/qla_gs.c @@ -4290,7 +4290,7 @@ int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t *fcport) if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT)) return rval; - fcport->disc_state = DSC_GNN_ID; + qla2x00_set_fcport_disc_state(fcport, DSC_GNN_ID); sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC); if (!sp) goto done; diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 0758b1cef..73de5ada9 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -316,10 +316,10 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport, if (!sp) goto done; + qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_PEND); fcport->flags |= FCF_ASYNC_SENT; fcport->logout_completed = 0; - fcport->disc_state = DSC_LOGIN_PEND; sp->type = SRB_LOGIN_CMD; sp->name = "login"; sp->gen1 = fcport->rscn_gen; @@ -523,7 +523,7 @@ static int qla_post_els_plogi_work(struct scsi_qla_host *vha, fc_port_t *fcport) e->u.fcport.fcport = fcport; fcport->flags |= FCF_ASYNC_ACTIVE; - fcport->disc_state = DSC_LOGIN_PEND; + qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_PEND); return qla2x00_post_work(vha, e); } @@ -826,7 +826,8 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha, * with GNL. Push disc_state back to DELETED * so GNL can go out again */ - fcport->disc_state = DSC_DELETED; + qla2x00_set_fcport_disc_state(fcport, + DSC_DELETED); break; case DSC_LS_PRLI_COMP: if ((e->prli_svc_param_word_3[0] & BIT_4) == 0) @@ -902,7 +903,7 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha, qla24xx_fcport_handle_login(vha, fcport); break; case ISP_CFG_N: - fcport->disc_state = DSC_DELETED; + qla2x00_set_fcport_disc_state(fcport, DSC_DELETED); if (time_after_eq(jiffies, fcport->dm_login_expire)) { if (fcport->n2n_link_reset_cnt < 2) { fcport->n2n_link_reset_cnt++; @@ -1062,7 +1063,7 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport) spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); fcport->flags |= FCF_ASYNC_SENT; - fcport->disc_state = DSC_GNL; + qla2x00_set_fcport_disc_state(fcport, DSC_GNL); fcport->last_rscn_gen = fcport->rscn_gen; fcport->last_login_gen = fcport->login_gen; @@ -1285,12 +1286,12 @@ int qla24xx_async_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt) return rval; } - fcport->disc_state = DSC_GPDB; - sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); if (!sp) goto done; + qla2x00_set_fcport_disc_state(fcport, DSC_GPDB); + fcport->flags |= FCF_ASYNC_SENT; sp->type = SRB_MB_IOCB; sp->name = "gpdb"; @@ -1369,7 +1370,7 @@ void __qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea) ql_dbg(ql_dbg_disc, vha, 0x20d6, "%s %d %8phC session revalidate success\n", __func__, __LINE__, ea->fcport->port_name); - ea->fcport->disc_state = DSC_LOGIN_COMPLETE; + qla2x00_set_fcport_disc_state(ea->fcport, DSC_LOGIN_COMPLETE); } spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); } @@ -1423,7 +1424,7 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea) /* Set discovery state back to GNL to Relogin attempt */ if (qla_dual_mode_enabled(vha) || qla_ini_mode_enabled(vha)) { - fcport->disc_state = DSC_GNL; + qla2x00_set_fcport_disc_state(fcport, DSC_GNL); set_bit(RELOGIN_NEEDED, &vha->dpc_flags); } return; @@ -2000,7 +2001,7 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) __func__, __LINE__, ea->fcport->port_name, ea->data[1]); ea->fcport->flags &= ~FCF_ASYNC_SENT; - ea->fcport->disc_state = DSC_LOGIN_FAILED; + qla2x00_set_fcport_disc_state(ea->fcport, DSC_LOGIN_FAILED); if (ea->data[1] & QLA_LOGIO_LOGIN_RETRIED) set_bit(RELOGIN_NEEDED, &vha->dpc_flags); else @@ -5389,7 +5390,7 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) ql_dbg(ql_dbg_disc, vha, 0x20ef, "%s %8phC\n", __func__, fcport->port_name); - fcport->disc_state = DSC_UPD_FCPORT; + qla2x00_set_fcport_disc_state(fcport, DSC_UPD_FCPORT); fcport->login_retry = vha->hw->login_retry_count; fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT); fcport->deleted = 0; @@ -5409,7 +5410,7 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) if (NVME_TARGET(vha->hw, fcport)) { qla_nvme_register_remote(vha, fcport); - fcport->disc_state = DSC_LOGIN_COMPLETE; + qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE); qla2x00_set_fcport_state(fcport, FCS_ONLINE); return; } @@ -5454,7 +5455,7 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) } } - fcport->disc_state = DSC_LOGIN_COMPLETE; + qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE); } void qla_register_fcport_fn(struct work_struct *work) @@ -5863,7 +5864,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha) if (NVME_TARGET(vha->hw, fcport)) { if (fcport->disc_state == DSC_DELETE_PEND) { - fcport->disc_state = DSC_GNL; + qla2x00_set_fcport_disc_state(fcport, DSC_GNL); vha->fcport_count--; fcport->login_succ = 0; } diff --git a/qla2x00t-32gbit/qla_inline.h b/qla2x00t-32gbit/qla_inline.h index 522bbf25f..ab40c8717 100644 --- a/qla2x00t-32gbit/qla_inline.h +++ b/qla2x00t-32gbit/qla_inline.h @@ -113,6 +113,30 @@ qla2x00_clean_dsd_pool(struct qla_hw_data *ha, struct crc_context *ctx) INIT_LIST_HEAD(&ctx->dsd_list); } +static inline void +qla2x00_set_fcport_disc_state(fc_port_t *fcport, int state) +{ + int old_val; + uint8_t shiftbits, mask; + + /* This will have to change when the max no. of states > 16 */ + shiftbits = 4; + mask = (1 << shiftbits) - 1; + + fcport->disc_state = state; + while (1) { + old_val = atomic_read(&fcport->shadow_disc_state); + if (old_val == atomic_cmpxchg(&fcport->shadow_disc_state, + old_val, (old_val << shiftbits) | state)) { + ql_dbg(ql_dbg_disc, fcport->vha, 0x2134, + "FCPort %8phC disc_state transition: %s to %s - portid=%06x.\n", + fcport->port_name, port_dstate_str[old_val & mask], + port_dstate_str[state], fcport->d_id.b24); + return; + } + } +} + static inline int qla2x00_hba_err_chk_enabled(srb_t *sp) { diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index c202c34ef..54cfe31de 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -2883,7 +2883,8 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res) fw_status[0], fw_status[1], fw_status[2]); fcport->flags &= ~FCF_ASYNC_SENT; - fcport->disc_state = DSC_LOGIN_FAILED; + qla2x00_set_fcport_disc_state(fcport, + DSC_LOGIN_FAILED); set_bit(RELOGIN_NEEDED, &vha->dpc_flags); break; } @@ -2896,7 +2897,7 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res) fw_status[0], fw_status[1], fw_status[2]); sp->fcport->flags &= ~FCF_ASYNC_SENT; - sp->fcport->disc_state = DSC_LOGIN_FAILED; + qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_FAILED); set_bit(RELOGIN_NEEDED, &vha->dpc_flags); break; } @@ -2933,7 +2934,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode, } fcport->flags |= FCF_ASYNC_SENT; - fcport->disc_state = DSC_LOGIN_PEND; + qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_PEND); elsio = &sp->u.iocb_cmd; ql_dbg(ql_dbg_io, vha, 0x3073, "Enter: PLOGI portid=%06x\n", fcport->d_id.b24); diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index 4188e5436..a4758735e 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -5052,7 +5052,7 @@ void qla24xx_sched_upd_fcport(fc_port_t *fcport) fcport->jiffies_at_registration = jiffies; fcport->sec_since_registration = 0; fcport->next_disc_state = DSC_DELETED; - fcport->disc_state = DSC_UPD_FCPORT; + qla2x00_set_fcport_disc_state(fcport, DSC_UPD_FCPORT); spin_unlock_irqrestore(&fcport->vha->work_lock, flags); #if defined(RHEL_MAJOR) && RHEL_MAJOR -0 <= 6 diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index fba835e4e..519361312 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -609,7 +609,8 @@ static void qla2x00_async_nack_sp_done(srb_t *sp, int res) spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); } else { sp->fcport->login_retry = 0; - sp->fcport->disc_state = DSC_LOGIN_COMPLETE; + qla2x00_set_fcport_disc_state(sp->fcport, + DSC_LOGIN_COMPLETE); sp->fcport->deleted = 0; sp->fcport->logout_on_delete = 1; } @@ -1065,7 +1066,7 @@ void qlt_free_session_done(struct work_struct *work) tgt->sess_count--; } - sess->disc_state = DSC_DELETED; + qla2x00_set_fcport_disc_state(sess, DSC_DELETED); sess->fw_login_state = DSC_LS_PORT_UNAVAIL; sess->deleted = QLA_SESS_DELETED; @@ -1170,7 +1171,7 @@ void qlt_unreg_sess(struct fc_port *sess) vha->hw->tgt.tgt_ops->clear_nacl_from_fcport_map(sess); sess->deleted = QLA_SESS_DELETION_IN_PROGRESS; - sess->disc_state = DSC_DELETE_PEND; + qla2x00_set_fcport_disc_state(sess, DSC_DELETE_PEND); sess->last_rscn_gen = sess->rscn_gen; sess->last_login_gen = sess->login_gen; @@ -1270,7 +1271,7 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess) sess->deleted = QLA_SESS_DELETION_IN_PROGRESS; spin_unlock_irqrestore(&sess->vha->work_lock, flags); - sess->disc_state = DSC_DELETE_PEND; + qla2x00_set_fcport_disc_state(sess, DSC_DELETE_PEND); qla24xx_chk_fcp_state(sess); @@ -6107,7 +6108,7 @@ static fc_port_t *qlt_get_port_database(struct scsi_qla_host *vha, if (!IS_SW_RESV_ADDR(fcport->d_id)) vha->fcport_count++; fcport->login_gen++; - fcport->disc_state = DSC_LOGIN_COMPLETE; + qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE); fcport->login_succ = 1; newfcport = 1; } From b7ce0c846073b18c0bbc62b7a7d077c0be4f8407 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:38:04 +0000 Subject: [PATCH 45/57] qla2x00t-32gbit: Cleanup unused async_logout_done This patch removes unused qla2x00_async_logout_done from the code. Link: https://lore.kernel.org/r/20191217220617.28084-5-hmadhani@marvell.com Signed-off-by: Shyam Sundar Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit 96a0eb7164d125100ac692c7efeb6e70a7585042 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8745 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 1 - qla2x00t-32gbit/qla_gbl.h | 4 ---- qla2x00t-32gbit/qla_init.c | 10 ---------- qla2x00t-32gbit/qla_os.c | 5 ----- 4 files changed, 20 deletions(-) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index d2d56df65..69915214a 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -3304,7 +3304,6 @@ enum qla_work_type { QLA_EVT_IDC_ACK, QLA_EVT_ASYNC_LOGIN, QLA_EVT_ASYNC_LOGOUT, - QLA_EVT_ASYNC_LOGOUT_DONE, QLA_EVT_ASYNC_ADISC, QLA_EVT_UEVENT, QLA_EVT_AENFX, diff --git a/qla2x00t-32gbit/qla_gbl.h b/qla2x00t-32gbit/qla_gbl.h index 06ce1c5af..2a990ad89 100644 --- a/qla2x00t-32gbit/qla_gbl.h +++ b/qla2x00t-32gbit/qla_gbl.h @@ -72,8 +72,6 @@ extern int qla2x00_async_adisc(struct scsi_qla_host *, fc_port_t *, extern int qla2x00_async_tm_cmd(fc_port_t *, uint32_t, uint32_t, uint32_t); extern void qla2x00_async_login_done(struct scsi_qla_host *, fc_port_t *, uint16_t *); -extern void qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *, - uint16_t *); struct qla_work_evt *qla2x00_alloc_work(struct scsi_qla_host *, enum qla_work_type); extern int qla24xx_async_gnl(struct scsi_qla_host *, fc_port_t *); @@ -187,8 +185,6 @@ extern int qla2x00_post_async_login_work(struct scsi_qla_host *, fc_port_t *, uint16_t *); extern int qla2x00_post_async_logout_work(struct scsi_qla_host *, fc_port_t *, uint16_t *); -extern int qla2x00_post_async_logout_done_work(struct scsi_qla_host *, - fc_port_t *, uint16_t *); extern int qla2x00_post_async_adisc_work(struct scsi_qla_host *, fc_port_t *, uint16_t *); extern int qla2x00_post_async_adisc_done_work(struct scsi_qla_host *, diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 73de5ada9..f71c31350 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -2059,16 +2059,6 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) return; } -void -qla2x00_async_logout_done(struct scsi_qla_host *vha, fc_port_t *fcport, - uint16_t *data) -{ - qlt_logo_completion_handler(fcport, data[0]); - fcport->login_gen++; - fcport->flags &= ~FCF_ASYNC_ACTIVE; - return; -} - /****************************************************************************/ /* QLogic ISP2x00 Hardware Support Functions. */ /****************************************************************************/ diff --git a/qla2x00t-32gbit/qla_os.c b/qla2x00t-32gbit/qla_os.c index a4758735e..3b65ef45f 100644 --- a/qla2x00t-32gbit/qla_os.c +++ b/qla2x00t-32gbit/qla_os.c @@ -4985,7 +4985,6 @@ int qla2x00_post_async_##name##_work( \ qla2x00_post_async_work(login, QLA_EVT_ASYNC_LOGIN); qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT); -qla2x00_post_async_work(logout_done, QLA_EVT_ASYNC_LOGOUT_DONE); qla2x00_post_async_work(adisc, QLA_EVT_ASYNC_ADISC); qla2x00_post_async_work(prlo, QLA_EVT_ASYNC_PRLO); qla2x00_post_async_work(prlo_done, QLA_EVT_ASYNC_PRLO_DONE); @@ -5277,10 +5276,6 @@ qla2x00_do_work(struct scsi_qla_host *vha) case QLA_EVT_ASYNC_LOGOUT: rc = qla2x00_async_logout(vha, e->u.logio.fcport); break; - case QLA_EVT_ASYNC_LOGOUT_DONE: - qla2x00_async_logout_done(vha, e->u.logio.fcport, - e->u.logio.data); - break; case QLA_EVT_ASYNC_ADISC: qla2x00_async_adisc(vha, e->u.logio.fcport, e->u.logio.data); From 6c8601bc82fca931e11fac381f14546d460984c0 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:38:30 +0000 Subject: [PATCH 46/57] qla2x00t-32gbit: Fix update_fcport for current_topology logout_on_delete flag should not be set if the topology is Loop. This patch fixes unintentional logout during loop topology. Link: https://lore.kernel.org/r/20191217220617.28084-6-hmadhani@marvell.com Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit 89eb2e7e794da2691e5aca02ed102bb287e3575a upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8746 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index f71c31350..dd59bd30b 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -5384,7 +5384,10 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t *fcport) fcport->login_retry = vha->hw->login_retry_count; fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT); fcport->deleted = 0; - fcport->logout_on_delete = 1; + if (vha->hw->current_topology == ISP_CFG_NL) + fcport->logout_on_delete = 0; + else + fcport->logout_on_delete = 1; fcport->n2n_chip_reset = fcport->n2n_link_reset_cnt = 0; switch (vha->hw->current_topology) { From 6892c836531d44fe5e577cbd8b400d5f98f05bfb Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:38:50 +0000 Subject: [PATCH 47/57] qla2x00t-32gbit: Add D-Port Diagnostic reason explanation logs This patch adds more details when D-Port diag async event is generated by the firmware. Link: https://lore.kernel.org/r/20191217220617.28084-7-hmadhani@marvell.com Signed-off-by: Joe Carnuccio Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit 425215647fc53ba183026e03206fa86fe5a4f542 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8747 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_isr.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/qla2x00t-32gbit/qla_isr.c b/qla2x00t-32gbit/qla_isr.c index b42cf0bbc..9bede48c8 100644 --- a/qla2x00t-32gbit/qla_isr.c +++ b/qla2x00t-32gbit/qla_isr.c @@ -1264,11 +1264,33 @@ global_port_update: case MBA_DPORT_DIAGNOSTICS: ql_dbg(ql_dbg_async, vha, 0x5052, - "D-Port Diagnostics: %04x result=%s\n", - mb[0], - mb[1] == 0 ? "start" : - mb[1] == 1 ? "done (pass)" : - mb[1] == 2 ? "done (error)" : "other"); + "D-Port Diagnostics: %04x %04x %04x %04x\n", + mb[0], mb[1], mb[2], mb[3]); + if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) { + static char *results[] = { + "start", "done(pass)", "done(error)", "undefined" }; + static char *types[] = { + "none", "dynamic", "static", "other" }; + uint result = mb[1] >> 0 & 0x3; + uint type = mb[1] >> 6 & 0x3; + uint sw = mb[1] >> 15 & 0x1; + ql_dbg(ql_dbg_async, vha, 0x5052, + "D-Port Diagnostics: result=%s type=%s [sw=%u]\n", + results[result], types[type], sw); + if (result == 2) { + static char *reasons[] = { + "reserved", "unexpected reject", + "unexpected phase", "retry exceeded", + "timed out", "not supported", + "user stopped" }; + uint reason = mb[2] >> 0 & 0xf; + uint phase = mb[2] >> 12 & 0xf; + ql_dbg(ql_dbg_async, vha, 0x5052, + "D-Port Diagnostics: reason=%s phase=%u \n", + reason < 7 ? reasons[reason] : "other", + phase >> 1); + } + } break; case MBA_TEMPERATURE_ALERT: From d65276050d8498b89f414d1c6506decbf08dc360 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:39:13 +0000 Subject: [PATCH 48/57] qla2x00t-32gbit: Use common routine to free fcport struct This patch does not change any any functionality. Link: https://lore.kernel.org/r/20191217220617.28084-8-hmadhani@marvell.com Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit 3dae220595baa7a9fb582b851b54c10ad6a0cbae upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8748 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_bsg.c | 9 +++++---- qla2x00t-32gbit/qla_gbl.h | 1 + qla2x00t-32gbit/qla_init.c | 2 +- qla2x00t-32gbit/qla_mr.c | 6 +++--- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/qla2x00t-32gbit/qla_bsg.c b/qla2x00t-32gbit/qla_bsg.c index b6af6cd7e..14b3df646 100644 --- a/qla2x00t-32gbit/qla_bsg.c +++ b/qla2x00t-32gbit/qla_bsg.c @@ -83,7 +83,8 @@ void qla2x00_bsg_sp_free(srb_t *sp) if (sp->type == SRB_CT_CMD || sp->type == SRB_FXIOCB_BCMD || sp->type == SRB_ELS_CMD_HST) - kfree(sp->fcport); + qla2x00_free_fcport(sp->fcport); + qla2x00_rel_sp(sp); } @@ -444,7 +445,7 @@ done_unmap_sg: done_free_fcport: if (bsg_request->msgcode == FC_BSG_RPT_ELS) - kfree(fcport); + qla2x00_free_fcport(fcport); done: return rval; } @@ -589,7 +590,7 @@ qla2x00_process_ct(struct bsg_job *bsg_job) return rval; done_free_fcport: - kfree(fcport); + qla2x00_free_fcport(fcport); done_unmap_sg: dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE); @@ -2169,7 +2170,7 @@ qlafx00_mgmt_cmd(struct bsg_job *bsg_job) return rval; done_free_fcport: - kfree(fcport); + qla2x00_free_fcport(fcport); done_unmap_rsp_sg: if (piocb_rqst->flags & SRB_FXDISC_RESP_DMA_VALID) diff --git a/qla2x00t-32gbit/qla_gbl.h b/qla2x00t-32gbit/qla_gbl.h index 2a990ad89..83b03e037 100644 --- a/qla2x00t-32gbit/qla_gbl.h +++ b/qla2x00t-32gbit/qla_gbl.h @@ -202,6 +202,7 @@ extern void qla2x00_free_host(struct scsi_qla_host *); extern void qla2x00_relogin(struct scsi_qla_host *); extern void qla2x00_do_work(struct scsi_qla_host *); extern void qla2x00_free_fcports(struct scsi_qla_host *); +extern void qla2x00_free_fcport(fc_port_t *); extern void qla83xx_schedule_work(scsi_qla_host_t *, int); extern void qla83xx_service_idc_aen(struct work_struct *); diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index dd59bd30b..67f7c21ed 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -5246,7 +5246,7 @@ skip_login: } cleanup_allocation: - kfree(new_fcport); + qla2x00_free_fcport(new_fcport); if (rval != QLA_SUCCESS) { ql_dbg(ql_dbg_disc, vha, 0x2098, diff --git a/qla2x00t-32gbit/qla_mr.c b/qla2x00t-32gbit/qla_mr.c index 116d586d8..8078f1525 100644 --- a/qla2x00t-32gbit/qla_mr.c +++ b/qla2x00t-32gbit/qla_mr.c @@ -1212,7 +1212,7 @@ qlafx00_find_all_targets(scsi_qla_host_t *vha, fcport->old_tgt_id); qla2x00_mark_device_lost(vha, fcport, 0); set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); - kfree(new_fcport); + qla2x00_free_fcport(new_fcport); return rval; } break; @@ -1230,7 +1230,7 @@ qlafx00_find_all_targets(scsi_qla_host_t *vha, return QLA_MEMORY_ALLOC_FAILED; } - kfree(new_fcport); + qla2x00_free_fcport(new_fcport); return rval; } @@ -1298,7 +1298,7 @@ qlafx00_configure_all_targets(scsi_qla_host_t *vha) /* Free all new device structures not processed. */ list_for_each_entry_safe(fcport, rmptemp, &new_fcports, list) { list_del(&fcport->list); - kfree(fcport); + qla2x00_free_fcport(fcport); } return rval; From c8fe6bdf91e7eb4c13686c5be2c3f7fee1069871 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:39:34 +0000 Subject: [PATCH 49/57] qla2x00t-32gbit: Fix stuck login session using prli_pend_timer Session is stuck if driver sees FW has received a PRLI. Driver allows FW to finish with processing of PRLI by checking back with FW at a later time to see if the PRLI has finished. Instead, driver failed to push forward after re-checking PRLI completion. Fixes: 974950710e2a ("qla2xxx: Fix stuck login session") Cc: stable@vger.kernel.org # 5.3 Link: https://lore.kernel.org/r/20191217220617.28084-9-hmadhani@marvell.com Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit 08c0de658b08408284e5176d585782f924a21173 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8749 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_def.h | 5 +++++ qla2x00t-32gbit/qla_init.c | 34 ++++++++++++++++++++++++++-------- qla2x00t-32gbit/qla_target.c | 1 + 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/qla2x00t-32gbit/qla_def.h b/qla2x00t-32gbit/qla_def.h index 69915214a..e336f03a9 100644 --- a/qla2x00t-32gbit/qla_def.h +++ b/qla2x00t-32gbit/qla_def.h @@ -2428,6 +2428,7 @@ typedef struct fc_port { unsigned int scan_needed:1; unsigned int n2n_flag:1; unsigned int explicit_logout:1; + unsigned int prli_pend_timer:1; struct completion nvme_del_done; uint32_t nvme_prli_service_param; @@ -2454,6 +2455,7 @@ typedef struct fc_port { struct work_struct free_work; struct work_struct reg_work; uint64_t jiffies_at_registration; + unsigned long prli_expired; struct qlt_plogi_ack_t *plogi_link[QLT_PLOGI_LINK_MAX]; struct completion *unreg_done; @@ -4885,6 +4887,9 @@ struct sff_8247_a0 { (ha->fc4_type_priority == FC4_PRIORITY_NVME)) || \ NVME_ONLY_TARGET(fcport)) \ +#define PRLI_PHASE(_cls) \ + ((_cls == DSC_LS_PRLI_PEND) || (_cls == DSC_LS_PRLI_COMP)) + #include "qla_target.h" #include "qla_gbl.h" #include "qla_dbg.h" diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 67f7c21ed..37aad8da7 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -675,7 +675,7 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha, port_id_t id; u64 wwn; u16 data[2]; - u8 current_login_state; + u8 current_login_state, nvme_cls; fcport = ea->fcport; ql_dbg(ql_dbg_disc, vha, 0xffff, @@ -734,10 +734,17 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha, loop_id = le16_to_cpu(e->nport_handle); loop_id = (loop_id & 0x7fff); - if (NVME_TARGET(vha->hw, fcport)) - current_login_state = e->current_login_state >> 4; - else - current_login_state = e->current_login_state & 0xf; + nvme_cls = e->current_login_state >> 4; + current_login_state = e->current_login_state & 0xf; + + if (PRLI_PHASE(nvme_cls)) { + current_login_state = nvme_cls; + fcport->fc4_type &= ~FS_FC4TYPE_FCP; + fcport->fc4_type |= FS_FC4TYPE_NVME; + } else if (PRLI_PHASE(current_login_state)) { + fcport->fc4_type |= FS_FC4TYPE_FCP; + fcport->fc4_type &= ~FS_FC4TYPE_NVME; + } ql_dbg(ql_dbg_disc, vha, 0x20e2, "%s found %8phC CLS [%x|%x] fc4_type %d ID[%06x|%06x] lid[%d|%d]\n", @@ -1207,12 +1214,19 @@ qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport) struct srb_iocb *lio; int rval = QLA_FUNCTION_FAILED; - if (!vha->flags.online) + if (!vha->flags.online) { + ql_dbg(ql_dbg_disc, vha, 0xffff, "%s %d %8phC exit\n", + __func__, __LINE__, fcport->port_name); return rval; + } - if (fcport->fw_login_state == DSC_LS_PLOGI_PEND || - fcport->fw_login_state == DSC_LS_PRLI_PEND) + if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND || + fcport->fw_login_state == DSC_LS_PRLI_PEND) && + qla_dual_mode_enabled(vha)) { + ql_dbg(ql_dbg_disc, vha, 0xffff, "%s %d %8phC exit\n", + __func__, __LINE__, fcport->port_name); return rval; + } sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); if (!sp) @@ -1591,6 +1605,10 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport) break; default: if (fcport->login_pause) { + ql_dbg(ql_dbg_disc, vha, 0x20d8, + "%s %d %8phC exit\n", + __func__, __LINE__, + fcport->port_name); fcport->last_rscn_gen = fcport->rscn_gen; fcport->last_login_gen = fcport->login_gen; set_bit(RELOGIN_NEEDED, &vha->dpc_flags); diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index 519361312..7ef3f11c2 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -1271,6 +1271,7 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess) sess->deleted = QLA_SESS_DELETION_IN_PROGRESS; spin_unlock_irqrestore(&sess->vha->work_lock, flags); + sess->prli_pend_timer = 0; qla2x00_set_fcport_disc_state(sess, DSC_DELETE_PEND); qla24xx_chk_fcp_state(sess); From 9d2b5a9184787e212ccce51f3193e44a7b34dba5 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:40:05 +0000 Subject: [PATCH 50/57] qla2x00t-32gbit: Correct fcport flags handling This patch fixes some instances of FCF_ASYNC_{SENT|ACTIVE} flag setting and clearning were missing. Link: https://lore.kernel.org/r/20191217220617.28084-10-hmadhani@marvell.com Signed-off-by: Shyam Sundar Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit 0333e5f4f5d3edb2d0f43ea0f4befd20aaf812b4 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8750 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_gs.c | 4 ---- qla2x00t-32gbit/qla_init.c | 3 ++- qla2x00t-32gbit/qla_iocb.c | 3 ++- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/qla2x00t-32gbit/qla_gs.c b/qla2x00t-32gbit/qla_gs.c index f11fb00bf..aaa4a5bbf 100644 --- a/qla2x00t-32gbit/qla_gs.c +++ b/qla2x00t-32gbit/qla_gs.c @@ -2963,7 +2963,6 @@ int qla24xx_post_gpsc_work(struct scsi_qla_host *vha, fc_port_t *fcport) return QLA_FUNCTION_FAILED; e->u.fcport.fcport = fcport; - fcport->flags |= FCF_ASYNC_ACTIVE; return qla2x00_post_work(vha, e); } @@ -3097,9 +3096,7 @@ int qla24xx_async_gpsc(scsi_qla_host_t *vha, fc_port_t *fcport) done_free_sp: sp->free(sp); - fcport->flags &= ~FCF_ASYNC_SENT; done: - fcport->flags &= ~FCF_ASYNC_ACTIVE; return rval; } @@ -4464,7 +4461,6 @@ int qla24xx_async_gfpnid(scsi_qla_host_t *vha, fc_port_t *fcport) done_free_sp: sp->free(sp); - fcport->flags &= ~FCF_ASYNC_SENT; done: return rval; } diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 37aad8da7..77e54e7a3 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -1119,8 +1119,8 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, fc_port_t *fcport) done_free_sp: sp->free(sp); - fcport->flags &= ~FCF_ASYNC_SENT; done: + fcport->flags &= ~(FCF_ASYNC_ACTIVE | FCF_ASYNC_SENT); return rval; } @@ -1354,6 +1354,7 @@ done_free_sp: sp->free(sp); fcport->flags &= ~FCF_ASYNC_SENT; done: + fcport->flags &= ~FCF_ASYNC_ACTIVE; qla24xx_post_gpdb_work(vha, fcport, opt); return rval; } diff --git a/qla2x00t-32gbit/qla_iocb.c b/qla2x00t-32gbit/qla_iocb.c index 54cfe31de..92aebc721 100644 --- a/qla2x00t-32gbit/qla_iocb.c +++ b/qla2x00t-32gbit/qla_iocb.c @@ -2930,6 +2930,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode, if (!sp) { ql_log(ql_log_info, vha, 0x70e6, "SRB allocation failed\n"); + fcport->flags &= ~FCF_ASYNC_ACTIVE; return -ENOMEM; } @@ -3007,7 +3008,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int els_opcode, } out: - fcport->flags &= ~(FCF_ASYNC_SENT); + fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); qla2x00_els_dcmd2_free(vha, &elsio->u.els_plogi); sp->free(sp); done: From a838112bdbf6c215e24b8208be14c9ffbe739e55 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:40:25 +0000 Subject: [PATCH 51/57] qla2x00t-32gbit: Consolidate fabric scan Consolidate scan for fabric loop and fabric topologies into a single scan. Link: https://lore.kernel.org/r/20191217220617.28084-11-hmadhani@marvell.com Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit 25009f0e147951f02618d71e4671a3104e2bb552 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8751 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 77e54e7a3..4f849b12b 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -4939,12 +4939,8 @@ qla2x00_configure_loop(scsi_qla_host_t *vha) qla2x00_get_data_rate(vha); /* Determine what we need to do */ - if (ha->current_topology == ISP_CFG_FL && - (test_bit(LOCAL_LOOP_UPDATE, &flags))) { - - set_bit(RSCN_UPDATE, &flags); - - } else if (ha->current_topology == ISP_CFG_F && + if ((ha->current_topology == ISP_CFG_FL || + ha->current_topology == ISP_CFG_F) && (test_bit(LOCAL_LOOP_UPDATE, &flags))) { set_bit(RSCN_UPDATE, &flags); From 22c88c268627083eb007fd90ca641ed6ed8728b2 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:40:58 +0000 Subject: [PATCH 52/57] qla2x00t-32gbit: Fix RIDA Format-2 This patch fixes offset for Format-2 data structure for Report ID Acquisition. This caused driver to set remote_nport_id to 0x0000 in N2N configuration. In a scenario where initiator's WWPN is higher than target's WWPN, driver will assign 0x00 as target nport-id, which results into login failure. Link: https://lore.kernel.org/r/20191217220617.28084-12-hmadhani@marvell.com Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit 101346ec73d9376823e7471b719c2e8445aa3541 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8752 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_fw.h | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/qla2x00t-32gbit/qla_fw.h b/qla2x00t-32gbit/qla_fw.h index 2ea212e0e..b4cc6de58 100644 --- a/qla2x00t-32gbit/qla_fw.h +++ b/qla2x00t-32gbit/qla_fw.h @@ -1366,12 +1366,12 @@ struct vp_rpt_id_entry_24xx { uint8_t port_id[3]; uint8_t format; union { - struct { + struct _f0 { /* format 0 loop */ uint8_t vp_idx_map[16]; uint8_t reserved_4[32]; } f0; - struct { + struct _f1 { /* format 1 fabric */ uint8_t vpstat1_subcode; /* vp_status=1 subcode */ uint8_t flags; @@ -1393,21 +1393,22 @@ struct vp_rpt_id_entry_24xx { uint16_t bbcr; uint8_t reserved_5[6]; } f1; - struct { /* format 2: N2N direct connect */ - uint8_t vpstat1_subcode; - uint8_t flags; - uint16_t rsv6; - uint8_t rsv2[12]; + struct _f2 { /* format 2: N2N direct connect */ + uint8_t vpstat1_subcode; + uint8_t flags; + uint16_t fip_flags; + uint8_t rsv2[12]; - uint8_t ls_rjt_vendor; - uint8_t ls_rjt_explanation; - uint8_t ls_rjt_reason; - uint8_t rsv3[5]; + uint8_t ls_rjt_vendor; + uint8_t ls_rjt_explanation; + uint8_t ls_rjt_reason; + uint8_t rsv3[5]; - uint8_t port_name[8]; - uint8_t node_name[8]; - uint8_t remote_nport_id[4]; - uint32_t reserved_5; + uint8_t port_name[8]; + uint8_t node_name[8]; + uint16_t bbcr; + uint8_t reserved_5[2]; + uint8_t remote_nport_id[4]; } f2; } u; }; From c75fc9910e762e898ad04ffb4ee1f28794a03542 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:41:20 +0000 Subject: [PATCH 53/57] qla2x00t-32gbit: Fix stuck session in GNL Fix race condition between GNL completion processing and GNL request. Late submission of GNL request was not seen by the GNL completion thread. This patch will re-submit the GNL request for late submission fcport. Link: https://lore.kernel.org/r/20191217220617.28084-13-hmadhani@marvell.com Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit 5c3f46d332234b833ed733144fb9dd40577eb8bc upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8753 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_init.c | 15 +++++++++++++-- qla2x00t-32gbit/qla_target.c | 21 +++++++++++++++------ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/qla2x00t-32gbit/qla_init.c b/qla2x00t-32gbit/qla_init.c index 4f849b12b..a5076f43e 100644 --- a/qla2x00t-32gbit/qla_init.c +++ b/qla2x00t-32gbit/qla_init.c @@ -990,7 +990,7 @@ static void qla24xx_async_gnl_sp_done(srb_t *sp, int res) set_bit(loop_id, vha->hw->loop_id_map); wwn = wwn_to_u64(e->port_name); - ql_dbg(ql_dbg_disc + ql_dbg_verbose, vha, 0x20e8, + ql_dbg(ql_dbg_disc, vha, 0x20e8, "%s %8phC %02x:%02x:%02x CLS %x/%x lid %x \n", __func__, (void *)&wwn, e->port_id[2], e->port_id[1], e->port_id[0], e->current_login_state, e->last_login_state, @@ -1049,6 +1049,16 @@ static void qla24xx_async_gnl_sp_done(srb_t *sp, int res) spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); vha->gnl.sent = 0; + if (!list_empty(&vha->gnl.fcports)) { + /* retrigger gnl */ + list_for_each_entry_safe(fcport, tf, &vha->gnl.fcports, + gnl_entry) { + list_del_init(&fcport->gnl_entry); + fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE); + if (qla24xx_post_gnl_work(vha, fcport) == QLA_SUCCESS) + break; + } + } spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); sp->free(sp); @@ -2000,7 +2010,7 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) qla24xx_post_prli_work(vha, ea->fcport); } else { ql_dbg(ql_dbg_disc, vha, 0x20ea, - "%s %d %8phC LoopID 0x%x in use with %06x. post gnl\n", + "%s %d %8phC LoopID 0x%x in use with %06x. post gpdb\n", __func__, __LINE__, ea->fcport->port_name, ea->fcport->loop_id, ea->fcport->d_id.b24); @@ -2071,6 +2081,7 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea) set_bit(lid, vha->hw->loop_id_map); ea->fcport->loop_id = lid; 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_target.c b/qla2x00t-32gbit/qla_target.c index 7ef3f11c2..84e4d983b 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -971,7 +971,7 @@ void qlt_free_session_done(struct work_struct *work) struct qlt_plogi_ack_t *own = sess->plogi_link[QLT_PLOGI_LINK_SAME_WWN]; - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf084, + ql_dbg(ql_dbg_disc, vha, 0xf084, "%s: se_sess %p / sess %p from port %8phC loop_id %#04x" " s_id %02x:%02x:%02x logout %d keep %d els_logo %d\n", __func__, sess->se_sess, sess, sess->port_name, sess->loop_id, @@ -1038,7 +1038,7 @@ void qlt_free_session_done(struct work_struct *work) while (!READ_ONCE(sess->logout_completed)) { if (!traced) { - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf086, + ql_dbg(ql_dbg_disc, vha, 0xf086, "%s: waiting for sess %p logout\n", __func__, sess); traced = true; @@ -1059,6 +1059,10 @@ void qlt_free_session_done(struct work_struct *work) (struct imm_ntfy_from_isp *)sess->iocb, SRB_NACK_LOGO); } + spin_lock_irqsave(&vha->work_lock, flags); + sess->flags &= ~FCF_ASYNC_SENT; + spin_unlock_irqrestore(&vha->work_lock, flags); + spin_lock_irqsave(&ha->tgt.sess_lock, flags); if (sess->se_sess) { sess->se_sess = NULL; @@ -1122,7 +1126,7 @@ void qlt_free_session_done(struct work_struct *work) spin_unlock_irqrestore(&ha->tgt.sess_lock, flags); sess->free_pending = 0; - ql_dbg(ql_dbg_tgt_mgt, vha, 0xf001, + ql_dbg(ql_dbg_disc, vha, 0xf001, "Unregistration of sess %p %8phC finished fcp_cnt %d\n", sess, sess->port_name, vha->fcport_count); @@ -1165,6 +1169,11 @@ void qlt_unreg_sess(struct fc_port *sess) return; } sess->free_pending = 1; + /* + * Use FCF_ASYNC_SENT flag to block other cmds used in sess + * management from being sent. + */ + sess->flags |= FCF_ASYNC_SENT; spin_unlock_irqrestore(&sess->vha->work_lock, flags); if (sess->se_sess) @@ -4641,7 +4650,7 @@ qlt_find_sess_invalidate_other(scsi_qla_host_t *vha, uint64_t wwn, /* find other sess with nport_id collision */ if (port_id.b24 == other_sess->d_id.b24) { if (loop_id != other_sess->loop_id) { - ql_dbg(ql_dbg_tgt_tmr, vha, 0x1000c, + ql_dbg(ql_dbg_disc, vha, 0x1000c, "Invalidating sess %p loop_id %d wwn %llx.\n", other_sess, other_sess->loop_id, other_wwn); @@ -4657,7 +4666,7 @@ qlt_find_sess_invalidate_other(scsi_qla_host_t *vha, uint64_t wwn, * Another wwn used to have our s_id/loop_id * kill the session, but don't free the loop_id */ - ql_dbg(ql_dbg_tgt_tmr, vha, 0xf01b, + ql_dbg(ql_dbg_disc, vha, 0xf01b, "Invalidating sess %p loop_id %d wwn %llx.\n", other_sess, other_sess->loop_id, other_wwn); @@ -4672,7 +4681,7 @@ qlt_find_sess_invalidate_other(scsi_qla_host_t *vha, uint64_t wwn, /* find other sess with nport handle collision */ if ((loop_id == other_sess->loop_id) && (loop_id != FC_NO_LOOP_ID)) { - ql_dbg(ql_dbg_tgt_tmr, vha, 0x1000d, + ql_dbg(ql_dbg_disc, vha, 0x1000d, "Invalidating sess %p loop_id %d wwn %llx.\n", other_sess, other_sess->loop_id, other_wwn); From cbe98a9ce7908043b0ade12509dd3be0064ba294 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:41:45 +0000 Subject: [PATCH 54/57] qla2x00t-32gbit: Fix mtcp dump collection failure MTCP dump failed due to MB Reg 10 was picking garbage data from stack memory. Fixes: 81178772b636a ("[SCSI] qla2xxx: Implemetation of mctp.") Cc: stable@vger.kernel.org Link: https://lore.kernel.org/r/20191217220617.28084-14-hmadhani@marvell.com Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit 7ae8c12cb1a5278795afbefabc67b119fe769b61 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8754 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_mbx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_mbx.c b/qla2x00t-32gbit/qla_mbx.c index b7c1108c4..9e09964f5 100644 --- a/qla2x00t-32gbit/qla_mbx.c +++ b/qla2x00t-32gbit/qla_mbx.c @@ -6152,9 +6152,8 @@ qla2x00_dump_mctp_data(scsi_qla_host_t *vha, dma_addr_t req_dma, uint32_t addr, mcp->mb[7] = LSW(MSD(req_dma)); mcp->mb[8] = MSW(addr); /* Setting RAM ID to valid */ - mcp->mb[10] |= BIT_7; /* For MCTP RAM ID is 0x40 */ - mcp->mb[10] |= 0x40; + mcp->mb[10] = BIT_7 | 0x40; mcp->out_mb |= MBX_10|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1| MBX_0; From 3f63399dffb14ff46afbeb26155c9c03f6498015 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:42:06 +0000 Subject: [PATCH 55/57] qla2x00t-32gbit: Update driver version to 10.01.00.22-k Link: https://lore.kernel.org/r/20191217220617.28084-15-hmadhani@marvell.com Signed-off-by: Himanshu Madhani Signed-off-by: Martin K. Petersen [ commit e849efe8c8734aee0d207a1f006705d7a6d8dd39 upstream ] git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8755 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qla2x00t-32gbit/qla_version.h b/qla2x00t-32gbit/qla_version.h index 03bd3b712..bb03c022e 100644 --- a/qla2x00t-32gbit/qla_version.h +++ b/qla2x00t-32gbit/qla_version.h @@ -7,7 +7,7 @@ /* * Driver version */ -#define QLA2XXX_VERSION "10.01.00.21-k" +#define QLA2XXX_VERSION "10.01.00.22-k" #define QLA_DRIVER_MAJOR_VER 10 #define QLA_DRIVER_MINOR_VER 1 From 4978587a5212cd6447456909c26ea08e77dfd78c Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:42:31 +0000 Subject: [PATCH 56/57] qla2x00t-32gbit: Fix a bug in qlt_alloc_qfull_cmd() Remove a memset() call that clears the data members initialized by sqa_qla2xxx_get_cmd(). Fixes: b8a1634ced7d ("qla2x00t-32gbit: Import this driver into the SCST repository") git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8756 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla_target.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index 84e4d983b..8bb511bde 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -5458,8 +5458,6 @@ qlt_alloc_qfull_cmd(struct scsi_qla_host *vha, return; } - memset(cmd, 0, sizeof(struct qla_tgt_cmd)); - qlt_incr_num_pend_cmds(vha); INIT_LIST_HEAD(&cmd->cmd_list); memcpy(&cmd->atio, atio, sizeof(*atio)); From 52370acb84856992e0dad86613fc9ca170ef58d1 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 26 Dec 2019 00:43:09 +0000 Subject: [PATCH 57/57] qla2x00t-32gbit: Reduce the size of struct qla_tgt_cmd git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@8757 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- qla2x00t-32gbit/qla2x00-target/scst_qla2xxx.c | 2 +- qla2x00t-32gbit/qla_target.c | 4 ++-- qla2x00t-32gbit/qla_target.h | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/qla2x00t-32gbit/qla2x00-target/scst_qla2xxx.c b/qla2x00t-32gbit/qla2x00-target/scst_qla2xxx.c index 9347c294f..97dbdd323 100644 --- a/qla2x00t-32gbit/qla2x00-target/scst_qla2xxx.c +++ b/qla2x00t-32gbit/qla2x00-target/scst_qla2xxx.c @@ -392,7 +392,6 @@ static struct qla_tgt_cmd *sqa_qla2xxx_get_cmd(struct fc_port *sess) #endif cmd->sess = sess; cmd->vha = sess->vha; - cmd->rel_cmd = sqa_qla2xxx_rel_cmd; return cmd; } @@ -1892,6 +1891,7 @@ static struct qla_tgt_func_tmpl sqa_qla2xxx_template = { .handle_data = sqa_qla2xxx_handle_data, .handle_tmr = sqa_qla2xxx_handle_tmr, .get_cmd = sqa_qla2xxx_get_cmd, + .rel_cmd = sqa_qla2xxx_rel_cmd, .free_cmd = sqa_qla2xxx_free_cmd, .free_mcmd = sqa_qla2xxx_free_mcmd, .free_session = sqa_qla2xxx_free_session, diff --git a/qla2x00t-32gbit/qla_target.c b/qla2x00t-32gbit/qla_target.c index 8bb511bde..72761eb53 100644 --- a/qla2x00t-32gbit/qla_target.c +++ b/qla2x00t-32gbit/qla_target.c @@ -3861,7 +3861,7 @@ void qlt_free_cmd(struct qla_tgt_cmd *cmd) return; } cmd->jiffies_at_free = get_jiffies_64(); - cmd->rel_cmd(cmd); + cmd->vha->hw->tgt.tgt_ops->rel_cmd(cmd); } EXPORT_SYMBOL(qlt_free_cmd); @@ -4198,7 +4198,7 @@ out_term: qlt_send_term_exchange(qpair, NULL, &cmd->atio, 1, 0); qlt_decr_num_pend_cmds(vha); - cmd->rel_cmd(cmd); + cmd->vha->hw->tgt.tgt_ops->rel_cmd(cmd); spin_unlock_irqrestore(qpair->qp_lock_ptr, flags); ha->tgt.tgt_ops->put_sess(sess); diff --git a/qla2x00t-32gbit/qla_target.h b/qla2x00t-32gbit/qla_target.h index 59d9f910a..7ba06300d 100644 --- a/qla2x00t-32gbit/qla_target.h +++ b/qla2x00t-32gbit/qla_target.h @@ -700,6 +700,7 @@ struct qla_tgt_func_tmpl { int (*handle_tmr)(struct qla_tgt_mgmt_cmd *, u64, uint16_t, uint32_t); struct qla_tgt_cmd *(*get_cmd)(struct fc_port *); + void (*rel_cmd)(struct qla_tgt_cmd *); void (*free_cmd)(struct qla_tgt_cmd *); void (*free_mcmd)(struct qla_tgt_mgmt_cmd *); void (*free_session)(struct fc_port *); @@ -968,7 +969,7 @@ struct qla_tgt_cmd { uint64_t jiffies_at_alloc; uint64_t jiffies_at_free; - void (*rel_cmd)(struct qla_tgt_cmd *); + enum trace_flags trc_flags; };